F# function, how it really works - f#

I got function like this one.
let c = (fun a b ‐> let d = a 10 in d ‐ 4*b) (fun c ‐> c + c) 5
let x = c‐6
That's what I understand so far:
"fun c ‐> c + c" is first argument for "fun a b" and "5" is second.
"let d" is kind a function that takes "a" and "b" and returns the result.
But if somebody could explain what exactly happened in:
let d = a 10 in d ‐ 4*b

in is used here as part of verbose syntax. You can rewrite it in leightweight syntax to make it a bit more readable. It would be something like that:
fun a b =
let d = a 10
d - 4 * b
a is invoked with 10 as argument and the results is assigned to d. Later on d - 4 * b is calculated and returned from the function.
For the example you have a is fun c -> c + c so invoking it with 10 returns 20.
20 - 4 * 5 = 0 so c is set to 0 and x will be 0 - 6 = -6.
From F# interactive:
> let c = (fun a b -> let d = a 10 in d - 4*b) (fun c -> c + c) 5;;
val c : int = 0

Related

Combine Observables

Let say I have
A: IObservable<int>
B: IObservable<int>
how can I combine these two into
C: IObservable<int>
which emitted value is a product of last observed values of A and B?
E.g.
A = [ 2 3 1 ]
B = [ 2 5 6 ]
then
C = [ 4 6 15 18 6 ]
I'm not terribly good at f# (more like a novice), but this seems to work:
let a = new Subject<int>()
let b = new Subject<int>()
let c = Observable.CombineLatest(a, b, Func<_,_,_>(fun x y -> x * y))
c.Subscribe(fun x -> printfn "%i" x) |> ignore
a.OnNext(2)
b.OnNext(2)
a.OnNext(3)
b.OnNext(5)
b.OnNext(6)
a.OnNext(1)
I get:
4
6
15
18
6

F# solution for Store Credit

I want to solve this excercise: http://code.google.com/codejam/contest/351101/dashboard#s=p0 using F#.
I am new to functional programming and F# but I like the concept and the language a lot. And I love the codejam excercise too it looks so easy but real life. Could somebody point me out a solution?
At the moment I have written this code which is just plain imperative and looks ugly from the functional perspective:
(*
C - Credit
L - Items
I - List of Integer, wher P is single integer
How does the data look like inside file
N
[...
* Money
* Items in store
...]
*)
let lines = System.IO.File.ReadAllLines("../../../../data/A-small-practice.in")
let CBounds c = c >= 5 && c <= 1000
let PBounds p = p >= 1 && p <= 1000
let entries = int(lines.[0]) - 1
let mutable index = 1 (* First index is how many entries*)
let mutable case = 1
for i = 0 to entries do
let index = (i*3) + 1
let C = int(lines.[index])
let L = int(lines.[index+1])
let I = lines.[index+2]
let items = I.Split([|' '|]) |> Array.map int
// C must be the sum of some items
// Ugly imperative way which contains duplicates
let mutable nIndex = 0
for n in items do
nIndex <- nIndex + 1
let mutable mIndex = nIndex
for m in items.[nIndex..] do
mIndex <- mIndex + 1
if n + m = C then do
printfn "Case #%A: %A %A" case nIndex mIndex
case <- case + 1
I would like to find out items which add up to C value but not in a usual imperative way - I want functional approach.
You don't specify how you would solve the problem, so it's hard to give advices.
Regarding reading inputs, you can express it as a series of transformation on Seq. High-order functions from Seq module are very handy:
let data =
"../../../../data/A-small-practice.in"
|> System.IO.File.ReadLines
|> Seq.skip 1
|> Seq.windowed 3
|> Seq.map (fun lines -> let C = int(lines.[0])
let L = int(lines.[1])
let items = lines.[2].Split([|' '|]) |> Array.map int
(C, L, items))
UPDATE:
For the rest of your example, you could use sequence expression. It is functional enough and easy to express nested computations:
let results =
seq {
for (C, _, items) in data do
for j in 1..items.Length-1 do
for i in 0..j-1 do
if items.[j] + items.[i] = C then yield (i, j)
}
Seq.iteri (fun case (i, j) -> printfn "Case #%A: %A %A" case i j) results

Is there a way to do a multiple value comparison inline?

I feel silly for even asking this because it seems so trivial but my brain is failing me. If I had the following:
let a, b, c = 1, 1, 1
Is there an eligant way to determine if a, b, and c all hold the same value. Something like:
let result = (a = b = c)
This fails because the expression a = b returns true and the next expression results in true = c and complains that it was expecting int, not bool. The only thing I can think of is:
a = b && a = c && b = c
which won't work when I want to add more variables.
Really what I'm trying to do is this:
let same (x: string * string * string) =
match x with
| (a, a, a) -> true
| _ -> false
I was hoping that I could match all the elements into one element and if they were different it would move on, but it says on the second element in the match that it has already been bound.
To check if every value in a list is the same:
let rec same = function
| x::y::_ when x <> y -> false
| _::xs -> same xs
| [] -> true
Usage
let a, b, c = 1, 1, 1
same [a; b; c] //true
let same (a, b, c) = a = b && b = c
I would try to use the forall function in order to determine if all of the numbers are same.
let list = [a; b; c;];;
List.forall (fun n -> n = a) list;;
val it : bool = true
This solution produces exactly the required syntax. Surprisingly to myself, is fairly fast. Also, is seems to be a good example of using monads, also known as Computation Expressions.
// Generic
let inline mOp1<'a> op sample x = op sample x, sample
let inline mOp2<'a> op1 op2 (b, sample) x = op1 b (op2 sample x), sample
// Implementation for (=) and (&&)
let (==) = mOp1 (=)
let (&=) = mOp2 (&&) (=)
// Use
let ret1 = a == b &= c &= d &= e |> fst
How it works
The approach is a very simplified State monad. The monadic type is a tuple of (bool, 'T). The first component is the boolean value of ongoing calculation, and the second is the sample value to compare with.
(==) would initialize the monad, similar to Delay operator.
(&=) is used for all subsequent comparisons. It is similar to Bind operator.
We don't need Return because fst would serve pretty fine.
mOp1 and mOp2 are abstractions over the logical operations. These allow defining your own operators. Here are examples of or-equal and and-greater-than:
let (|=) = mOp2 (||) (=)
let (.>) = mOp1 (>)
let (&>) = mOp2 (&&) (>)
// Use
let ret2 = a == b |= c |= d |= e |> fst // if any of b,c,d,e equals to a
let ret3 = 5 .> 3 &> 4 |> fst // true: 5>3 && 5>4
let ret4 = 5 .> 3 &> 8 &> 4 |> fst // false
Performance
I really enjoyed the beautiful solution by #ildjarn, but constructing List is quite slow, so my primary goal was performance.
Running a chain of 8 comparisons, 10 million times:
04972ms a=b && a=с && ...
23138ms List-based
12367ms monadic

F# fails with "Error 4 This expression was expected to have type int but here has type int -> int"

Here is the code that I am trying to get to work last line is where it is failing:
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 8051
let mutable d = 0
let mutable c = 1
let mutable xi = 2
let mutable yi = 2
let f x = (pown x 2) + (c % n);;
while c < 100 do
while d = 1 do
xi <- (f xi)
yi <- (f(f(yi)))
printfn "%d%d" xi yi
d <- gcd(abs (xi - yi) n)
---------------------The Following Code works; Except for integer overflow on N---------
module Factorization
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 600851475143N
let mutable d, c, xi, yi = 1, 1, 2, 2
let f x = (pown x 2) + (c % n);;
let maxN m =int(ceil(sqrt(float m)))
//if (n > maxN(xi)) && (n > maxN(yi)) then
while c < 100 do
d <- 1
while d = 1 do
if (maxN(n) > xi) && (maxN(n) > yi) then
xi <- f xi
yi <- f(f(yi))
d <- gcd (abs (xi - yi)) n
//fail
if d = n then d<-1
if d <> 1 then printfn "A prime factor of %d x = %d, y = %d, d = %d" n xi yi d
else
xi <- 2
yi <- 2
c <- c + 1;;
In addition to what #Rangoric pointed out, the outer brackets have to go as well otherwise currying won't work:
d <- gcd (abs(xi-yi)) n
Yikes, here are a few unsolicited tips (#BrokenGlass answered the question itself correctly).
First, you can assign all those mutables in one line:
let mutable d, c, xi, yi = 0, 1, 2, 2
Second, go easy on the parentheses:
xi <- f xi
yi <- f (f yi)
And of course, try to get rid of the mutables and while loops. But I'll leave that to you since I'm sure you are aware seeing that you implemented gcd using recursion.
Try:
d <- gcd (abs(xi-yi)) n
It is pointing out that abs is a int->int and not an int by itself. Wrapping it in parentheses causes the abs to be executed before gcd looks at it. This causes gcd to see the result of abs instead of abs itself.

help me explain this F# recursive example program

let rec aggregateList (f:int->int->int) init list =
match list with
| [] -> init
| hd::tl ->
let rem = aggregateList f init tl
f rem hd
let add a b = a + b
let mul a b = a * b
//to use in F# Interactive:
//aggregateList add 0 [1..5];;
Got this example from "Functional Programming for the Real world" by Thomas Petricek
I don't understand in second branch in that pattern matching: f rem hd.
Could somebody help me?
Let's break down the aggregateList function declaration first. The function takes three parameters:
A function, named f, that takes two ints and returns a third int.
The initial value to start aggregating with.
A list of values.
The function then matches the list it is supplied with one of two possibilities:
The list is empty, in which case it returns the value of init.
The list is not empty, in which case it takes the first item and assigns it to hd (or head) and the rest of the list and assigns it to tl (or tail). Then it performs the recursive call aggregateList f init tl. When that returns, it takes the result and assigns it to rem. Then it calls f on rem and hd.
As other people have pointed out, this does the same thing as the List.foldback function in the basic F# library.
Be careful, of course, to choose the init value properly because if you executed aggregateList mul 0 somelist;; you'll just get 0 no matter what list you supply.
It calls the function f (one of the parameters) giving it the result of the recursive call and the next item.
rem is the remainder, or in this case the result of the remainder of the values.
hd is the next item, as seen in the | hd::tl -> part of the pattern matching.
Effectively this aggregate function takes a function, a starting point, and a list. A way of representing the example line is:
(1 + (2 + (3 + (4 + (5 + 0)))))
Just for fun, let's do some printf style debugging:
> aggregateList (fun acc x -> printf "%i " x; acc + x) 0 [1..10];;
10 9 8 7 6 5 4 3 2 1 val it : int = 55
It looks like the function is equivalent to List.foldBack (or fold_right in other languages): it walks each item in the list from right to left and invokes a function f on them.
Let's re-write the function in a few different ways:
// functional version
let rec foldBack f seed = function
| [] -> seed
| x::xs -> let res = foldBack f seed xs in f res x
// imperative version
let foldBack f seed xs =
let mutable result = seed
for x in List.rev xs do
result <- f result x
result
// C# equivalent
public static U FoldBack<T, U>(Func<T, U> f, U seed, IEnumerable<T> xs) {
foreach(T x in xs.Reverse())
seed = f(seed, x);
return seed;
}
You'd use the function like this:
let sum = foldBack (+) 0 [1..10] // returns 55
let sumOfSquares = foldBack (fun acc x -> acc + x * x) 0 [1..10];; // 385
I don't understand in second branch in
that pattern matching: f rem hd. Could
somebody help me?
So let's start with what we already know about F# functions:
f is a function with the type int -> int -> int. You pass functions around as if they were any other variable like ints or strings.
You call functions by passing a space-separated list of arguments. f rem hd invokes the function f with two arguments, rem and hd.
The last expression evaluated in a function is treated as the function's return value.
So going back to the original function:
let rec aggregateList (f:int->int->int) init list =
match list with
| [] -> init
| hd::tl ->
let rem = aggregateList f init tl // 1
f rem hd // 2
In line 1, we call aggregateList recusively with tl. Since the list gets smaller and smaller, we're eventually going to hit the nil case, which returns init.
In line 2, f rem hd is the function's return value. However, since we recursed down the stack as we made our way to end of the list, we're going to call this function one for each element (in right-to-left order) as we walk back up the stack trace.
Given aggregateList (+) 0 [1..10], the nil case returns 0, so we call:
return value = f rem hd = f 0 10 = 0 + 10 = 10
return value = f rem hd = f 10 9 = 9 + 10 = 19
return value = f rem hd = f 19 8 = 19 + 8 = 27
return value = f rem hd = f 27 7 = 27 + 7 = 34
return value = f rem hd = f 34 6 = 34 + 6 = 40
return value = f rem hd = f 40 5 = 40 + 5 = 45
return value = f rem hd = f 45 4 = 45 + 4 = 49
return value = f rem hd = f 49 3 = 49 + 3 = 52
return value = f rem hd = f 52 2 = 52 + 2 = 54
return value = f rem hd = f 54 1 = 54 + 1 = 55
No more items in the list, so the whole function returns 55.
As you can imagine, the nested calls in aggregateList evaluate like this for a list of length n:
f (f (f (f (f (f (f (f init hdn) hdn-1) hdn-2) hdn-3) ... hd2) hd1) hd0

Resources