I can obtain the even numbers in a list using the lambda syntax:
[1..10] |> List.filter (fun x -> x % 2 = 0)
But I want get it with composition, like this:
[1..10] |> List.filter ((% 2) >> (= 0))
Error: stdin(7,37): error FS0010: Unexpected integer literal in expression. Expected ')' or other token.
F# does not support operator sections. You can partially apply an operator by enclosing it in parentheses, like so:
let five = (+) 2 3
let add2 = (+) 2
let alsoFive = add2 3
However, this will not allow you to partially apply the right argument of the operator. In other words, F# does not offer anything equivalent to Haskell expression (/ 2). This can be worked around for commutative operators, such as addition or multiplication, because (+ 2) === (2 +), which in F# can be expressed as ((+) 2), but not for non-commutative ones.
The best you can do is declare the section as a separate function, like this:
let mod2 x = x % 2
[1..10] |> List.filter (mod2 >> ((=) 0))
If you absolutely insist on not declaring any more functions, you could try to do with a flip:
[1..10] |> List.filter ((flip (%) 2) >> ((=) 0))
But sadly, F# standard library does not provide a flip function either, so you'd have to declare it yourself anyway:
let inline flip f a b = f b a
Personally, I would rather go for increased readability and declare an isEven function:
let isEven x = (x % 2) = 0
[1..10] |> List.filter isEven
I am interested to implement fold3, fold4 etc., similar to List.fold and List.fold2. e.g.
// TESTCASE
let polynomial (x:double) a b c = a*x + b*x*x + c*x*x*x
let A = [2.0; 3.0; 4.0; 5.0]
let B = [1.5; 1.0; 0.5; 0.2]
let C = [0.8; 0.01; 0.001; 0.0001]
let result = fold3 polynomial 0.7 A B C
// 2.0 * (0.7 ) + 1.5 * (0.7 )^2 + 0.8 * (0.7 )^3 -> 2.4094
// 3.0 * (2.4094) + 1.0 * (2.4094)^2 + 0.01 * (2.4094)^3 -> 13.173
// 4.0 * (13.173) + 0.5 * (13.173)^2 + 0.001 * (13.173)^3 -> 141.75
// 5.0 * (141.75) + 0.2 * (141.75)^2 + 0.0001 * (141.75)^3 -> 5011.964
//
// Output: result = 5011.964
My first method is grouping the 3 lists A, B, C, into a list of tuples, and then apply list.fold
let fold3 f x A B C =
List.map3 (fun a b c -> (a,b,c)) A B C
|> List.fold (fun acc (a,b,c) -> f acc a b c) x
// e.g. creates [(2.0,1.5,0.8); (3.0,1.0,0.01); ......]
My second method is to declare a mutable data, and use List.map3
let mutable result = 0.7
List.map3 (fun a b c ->
result <- polynomial result a b c // Change mutable data
// Output intermediate data
result) A B C
// Output from List.map3: [2.4094; 13.17327905; 141.7467853; 5011.963942]
// result mutable: 5011.963942
I would like to know if there are other ways to solve this problem. Thank you.
For fold3, you could just do zip3 and then fold:
let polynomial (x:double) (a, b, c) = a*x + b*x*x + c*x*x*x
List.zip3 A B C |> List.fold polynomial 0.7
But if you want this for the general case, then you need what we call "applicative functors".
First, imagine you have a list of functions and a list of values. Let's assume for now they're of the same size:
let fs = [ (fun x -> x+1); (fun x -> x+2); (fun x -> x+3) ]
let xs = [3;5;7]
And what you'd like to do (only natural) is to apply each function to each value. This is easily done with List.map2:
let apply fs xs = List.map2 (fun f x -> f x) fs xs
apply fs xs // Result = [4;7;10]
This operation "apply" is why these are called "applicative functors". Not just any ol' functors, but applicative ones. (the reason for why they're "functors" is a tad more complicated)
So far so good. But wait! What if each function in my list of functions returned another function?
let f1s = [ (fun x -> fun y -> x+y); (fun x -> fun y -> x-y); (fun x -> fun y -> x*y) ]
Or, if I remember that fun x -> fun y -> ... can be written in the short form of fun x y -> ...
let f1s = [ (fun x y -> x+y); (fun x y -> x-y); (fun x y -> x*y) ]
What if I apply such list of functions to my values? Well, naturally, I'll get another list of functions:
let f2s = apply f1s xs
// f2s = [ (fun y -> 3+y); (fun y -> 5+y); (fun y -> 7+y) ]
Hey, here's an idea! Since f2s is also a list of functions, can I apply it again? Well of course I can!
let ys = [1;2;3]
apply f2s ys // Result: [4;7;10]
Wait, what? What just happened?
I first applied the first list of functions to xs, and got another list of functions as a result. And then I applied that result to ys, and got a list of numbers.
We could rewrite that without intermediate variable f2s:
let f1s = [ (fun x y -> x+y); (fun x y -> x-y); (fun x y -> x*y) ]
let xs = [3;5;7]
let ys = [1;2;3]
apply (apply f1s xs) ys // Result: [4;7;10]
For extra convenience, this operation apply is usually expressed as an operator:
let (<*>) = apply
f1s <*> xs <*> ys
See what I did there? With this operator, it now looks very similar to just calling the function with two arguments. Neat.
But wait. What about our original task? In the original requirements we don't have a list of functions, we only have one single function.
Well, that can be easily fixed with another operation, let's call it "apply first". This operation will take a single function (not a list) plus a list of values, and apply this function to each value in the list:
let applyFirst f xs = List.map f xs
Oh, wait. That's just map. Silly me :-)
For extra convenience, this operation is usually also given an operator name:
let (<|>) = List.map
And now, I can do things like this:
let f x y = x + y
let xs = [3;5;7]
let ys = [1;2;3]
f <|> xs <*> ys // Result: [4;7;10]
Or this:
let f x y z = (x + y)*z
let xs = [3;5;7]
let ys = [1;2;3]
let zs = [1;-1;100]
f <|> xs <*> ys <*> zs // Result: [4;-7;1000]
Neat! I made it so I can apply arbitrary functions to lists of arguments at once!
Now, finally, you can apply this to your original problem:
let polynomial a b c (x:double) = a*x + b*x*x + c*x*x*x
let A = [2.0; 3.0; 4.0; 5.0]
let B = [1.5; 1.0; 0.5; 0.2]
let C = [0.8; 0.01; 0.001; 0.0001]
let ps = polynomial <|> A <*> B <*> C
let result = ps |> List.fold (fun x f -> f x) 0.7
The list ps consists of polynomial instances that are partially applied to corresponding elements of A, B, and C, and still expecting the final argument x. And on the next line, I simply fold over this list of functions, applying each of them to the result of the previous.
You could check the implementation for ideas:
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs
let fold<'T,'State> (f : 'State -> 'T -> 'State) (acc: 'State) (array:'T[]) =
checkNonNull "array" array
let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f)
let mutable state = acc
for i = 0 to array.Length-1 do
state <- f.Invoke(state,array.[i])
state
here's a few implementations for you:
let fold2<'a,'b,'State> (f : 'State -> 'a -> 'b -> 'State) (acc: 'State) (a:'a array) (b:'b array) =
let mutable state = acc
Array.iter2 (fun x y->state<-f state x y) a b
state
let iter3 f (a: 'a[]) (b: 'b[]) (c: 'c[]) =
let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f)
if a.Length <> b.Length || a.Length <> c.Length then failwithf "length"
for i = 0 to a.Length-1 do
f.Invoke(a.[i], b.[i], c.[i])
let altIter3 f (a: 'a[]) (b: 'b[]) (c: 'c[]) =
if a.Length <> b.Length || a.Length <> c.Length then failwithf "length"
for i = 0 to a.Length-1 do
f (a.[i]) (b.[i]) (c.[i])
let fold3<'a,'b,'State> (f : 'State -> 'a -> 'b -> 'c -> 'State) (acc: 'State) (a:'a array) (b:'b array) (c:'c array) =
let mutable state = acc
iter3 (fun x y z->state<-f state x y z) a b c
state
NB. we don't have an iter3, so, implement that. OptimizedClosures.FSharpFunc only allow up to 5 (or is it 7?) params. There are a finite number of type slots available. It makes sense. You can go higher than this, of course, without using the OptimizedClosures stuff.
... anyway, generally, you don't want to be iterating too many lists / arrays / sequences at once. So I'd caution against going too high.
... the better way forward in such cases may be to construct a record or tuple from said lists / arrays, first. Then, you can just use map and iter, which are already baked in. This is what zip / zip3 are all about (see: "(array1.[i],array2.[i],array3.[i])")
let zip3 (array1: _[]) (array2: _[]) (array3: _[]) =
checkNonNull "array1" array1
checkNonNull "array2" array2
checkNonNull "array3" array3
let len1 = array1.Length
if len1 <> array2.Length || len1 <> array3.Length then invalidArg3ArraysDifferent "array1" "array2" "array3" len1 array2.Length array3.Length
let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len1
for i = 0 to res.Length-1 do
res.[i] <- (array1.[i],array2.[i],array3.[i])
res
I'm working with arrays at the moment, so my solution pertained to those. Sorry about that. Here's a recursive version for lists.
let fold3 f acc a b c =
let mutable state = acc
let rec fold3 f a b c =
match a,b,c with
| [],[],[] -> ()
| [],_,_
| _,[],_
| _,_,[] -> failwith "length"
| ahead::atail, bhead::btail, chead::ctail ->
state <- f state ahead bhead chead
fold3 f atail btail ctail
fold3 f a b c
i.e. we define a recursive function within a function which acts upon/mutates/changes the outer scoped mutable acc variable (a closure in functional speak). Finally, this gets returned.
It's pretty cool how much type information gets inferred about these functions. In the array examples above, mostly I was explicit with 'a 'b 'c. This time, we let type inference kick in. It knows we're dealing with lists from the :: operator. That's kind of neat.
NB. the compiler will probably unwind this tail-recursive approach so that it is just a loop behind-the-scenes. Generally, get a correct answer before optimising. Just mentioning this, though, as food for later thought.
I think the existing answers provide great options if you want to generalize folding, which was your original question. However, if I simply wanted to call the polynomial function on inputs specified in A, B and C, then I would probably do not want to introduce fairly complex constructs like applicative functors with fancy operators to my code base.
The problem becomes a lot easier if you transpose the input data, so that rather than having a list [A; B; C] with lists for individual variables, you have a transposed list with inputs for calculating each polynomial. To do this, we'll need the transpose function:
let rec transpose = function
| (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M)
| _ -> []
Now you can create a list with inputs, transpose it and calculate all polynomials simply using List.map:
transpose [A; B; C]
|> List.map (function
| [a; b; c] -> polynomial 0.7 a b c
| _ -> failwith "wrong number of arguments")
There are many ways to solve this problem. Few are mentioned like first zip3 all three list, then run over it. Using Applicate Functors like Fyodor Soikin describes means you can turn any function with any amount of arguments into a function that expects list instead of single arguments. This is a good general solution that works with any numbers of lists.
While this is a general good idea, i'm sometimes shocked that so few use more low-level tools. In this case it is a good idea to use recursion and learn more about recursion.
Recursion here is the right-tool because we have immutable data-types. But you could consider how you would implement it with mutable lists and looping first, if that helps. The steps would be:
You loop over an index from 0 to the amount of elements in the lists.
You check if every list has an element for the index
If every list has an element then you pass this to your "folder" function
If at least one list don't have an element, then you abort the loop
The recursive version works exactly the same. Only that you don't use an index to access the elements. You would chop of the first element from every list and then recurse on the remaining list.
Otherwise List.isEmpty is the function to check if a List is empty. You can chop off the first element with List.head and you get the remaining list with the first element removed by List.tail. This way you can just write:
let rec fold3 f acc l1 l2 l3 =
let h = List.head
let t = List.tail
let empty = List.isEmpty
if (empty l1) || (empty l2) && (empty l3)
then acc
else fold3 f (f acc (h l1) (h l2) (h l3)) (t l1) (t l2) (t l3)
The if line checks if every list has at least one element. If that is true
it executes: f acc (h l1) (h l2) (h l3). So it executes f and passes it the first element of every list as an argument. The result is the new accumulator of
the next fold3 call.
Now that you worked on the first element of every list, you must chop off the first element of every list, and continue with the remaining lists. You achieve that with List.tail or in the above example (t l1) (t l2) (t l3). Those are the next remaining lists for the next fold3 call.
Creating a fold4, fold5, fold6 and so on isn't really hard, and I think it is self-explanatory. My general advice is to learn a little bit more about recursion and try to write recursive List functions without Pattern Matching. Pattern Matching is not always easier.
Some code examples:
fold3 (fun acc x y z -> x + y + z :: acc) [] [1;2;3] [10;20;30] [100;200;300] // [333;222;111]
fold3 (fun acc x y z -> x :: y :: z :: acc) [] [1;2;3] [10;20;30] [100;200;300] // [3; 30; 300; 2; 20; 200; 1; 10; 100]
Let's say I have following equation . My goal is to create sequence which returns next elements of this. Here's my solution and it works:
let rec factorial(n:float) =
match n with
|0.0 -> 1.0
|n -> n * factorial(n-1.0)
let seq1 = Seq.initInfinite( fun i -> factorial(float(i)) / sqrt(float(i)+1.0) ))
Now, analogically, I would like to create sequence which return elements according to equation:
I've got some code, but it's wrong so how to make it work?
let seq2(x:float) = Seq.initInfinite(fun a -> let i = float(a)
(1.0/factorial(0.0)) + System.Math.Pow(x,i)/factorial(i) )
Can't you skip the (1.0/factorial(0.0)) part of the equation (or maybe I misunderstood the question).
edit: i.e
let seq2(x:float) =
Seq.initInfinite(fun a ->
let i = float(a) in
System.Math.Pow(x,i)/factorial(i))
edit: to truncate a seq you can use 'take' and to sum you can use 'sum'. As in
let seq2sum nbelems =
seq2 >> Seq.take nbelems >> Seq.sum
then you get seq2sum 12 3.0 equal to approx 20 :-)
The great thing about functional languages is that you can have your solution be as close an expression of the original definition as possible.
You can avoid explicit type declarations for most functions:
let rec factorial = function
| 0 -> 1
| n -> n * (factorial (n-1))
let e x n =
seq { 0 .. n }
|> Seq.map(fun i -> x ** (float i) / float (factorial i))
|> Seq.sum
In the infinite series, you will have to take the first n entries before you sum, as an infinite series will never finish evaluating:
let e' x n =
Seq.initInfinite(fun i -> x ** (float i) / float (factorial i))
|> Seq.take n
|> Seq.sum
e 1.0 10 //2.718281801
e' 1.0 10 //2.718281801
have a code:
//e = 1/2*Sum((yi -di)^2)
let error y d =
let map =
Array.map2 (fun y d -> (y - d) ** 2.0) y d
let sum =
Array.sum map
(sum / 2.0)
let error2 y d =
Array.map2 (fun y d -> (y - d) ** 2.0) y d
|> Array.sum
|> (/) 2.0
as i understood those functions should produce the same results, but there are a big difference in the results. Can anyone explain this?
p.s. Simplified example:
let test = [|1..10|]
let res = test
|> Array.sum
|> (/) 5
i expect test = 11 (sum(1..10) = 55 and then 55 / 5) but after Array.sum pipeline is not working as i want(as result test = 0).
another alternative is to use the reverse pipe operator (<|) so that partial application of (/) is done with arguments in correct order:
let error2 y d =
Array.map2 (fun y d -> (y - d) ** 2.0) y d
|> Array.sum
|> (/) <| 2.0
Edit: see if this helps clarify
x/y = (/) x y = y |> (/) x = x |> (/) <| y
All those are equivalent. The pipe operators are defined as:
(|>) x f = f x
(<|) f x = f x
where f is a function and x is some value. The reverse pipe doesn't look like it does much but it can help clean up some code in certain situations.
You seem to misunderstand order of arguments in infix functions.
You can expand the point-free form as follows:
x |> (/) 5
<=> (/) 5 x
<=> 5 / x
So it's is the reverse of what you expect. It only works fine for commutative functions like (+), (*), etc. If you're keen on point-free style, the flip function is helpful to be used with |>:
let inline flip f x y = f y x
let error2 y d =
Array.map2 (fun y d -> (y - d) ** 2.0) y d
|> Array.sum
|> flip (/) 2.0
The / operator does not work the way you have assumed. You just need to be a bit more explicit and change the last line in error2 to
fun t -> t/2.0
and then it should all work.
The answers being out by a factor of 4 was the giveaway here.
EDIT: To understand what happens with / here consider what happens when you expand out |>
The following are all equivalent
a |> (/) b
((/) b) a //by removing |>
a / b //what happens when / is reinterpreted as a function
For example,
let fn x y = printfn "%i %i" x y
1 |> fn 2 // this is the same as fn 2 1 instead of fn 1 2
How to make it fn 1 2?
This is just a simplified example for test. I have a complex function return a value and I want to forward pipe it to the left side (in stead of right side) of a function.
I assume that you have at least two pipes. Otherwise, fn 1 2 does the job; why should we make it more complicated?
For commutative functions (which satisfy f x y = f y x) such as (+), (*), etc. you can just use 1 |> fn 2.
For other functions, I can see a few alternatives:
Use backward pipes
arg1
|> fn1
|> fn2 <| arg2
I tend to use this with care since operators' precedence might cause some subtle bugs.
Use flip function
let inline flip f x y = f y x
Array.map2 (fun y d -> (y - d) ** 2.0) y d
|> Array.sum
|> flip (/) 2.0
It's not pretty but it's clear that order of arguments in (/) is treated differently.
Use anonymous functions with fun and function keywords
This is handy if you need pattern matching in place.
input
|> createOption
|> function None -> 0 | Some _ -> 1
IMO, you don't have to pipe all the way. Create one more let binding, then your intention is clear and you can avoid bugs due to unusual styles.
let sum =
Array.map2 (fun y d -> (y - d) ** 2.0) y d
|> Array.sum
sum / 2.0
Here is a solution that looks pretty. I don't know if it is too practical though
1 |> fn <| 2