Quite similar to this question:
F# pipe first parameter
I am currently learning F# and functional programming, and I want to know if there is an easy way to pipe-forward a first argument (instead of last argument).
For example, if I want to pipe forward the last argument, it looks very nice and clean:
[4;5;6]
|> List.append [1;2;3]
// Result: [1;2;3;4;5;6]
If I want to pipe-forward the first argument, I can use a "fun x ->" function, but I am just curious if there is a cleaner way.
[1;2;3]
|> fun x -> List.append x [4;5;6]
// Result: [1;2;3;4;5;6]
Thank you very much.
P.S. My coworker just helped me with this problem. But I would appreciate any help if you have any suggestions for an F# beginner. Thank you.
When the order of arguments is inconvenient, you can always transform the function itself to make it take the arguments in a different order:
let flip f x y = f y x
[1; 2; 3]
|> (flip List.append) [4; 5; 6]
Transforming functions is useful in many contexts. It is a functional programmer's bread and butter.
But in the end, I believe, readability is most important: programs are read incomparably more often than they are written. When I find myself in a similar situation, and I don't want to name the intermediate value or use a lambda expression for some reason, I define myself a function that would be intuitive to understand:
let prependTo a b = List.append b a
[1; 2; 3]
|> prependTo [4; 5; 6]
All the existing answers provide good solution to the problem.
However, I think that if you want to use pipe to specify the first argument of a function, most of the time, it is not a good idea and you should just use an ordinary call without pipes:
List.append [1;2;3] [4;5;6]
The reason is that the "piping pattern" lets you write code that performs series of transformations on some data structure (list, etc.). Libraries designed to support the piping pattern will take the "main input" as the last argument to support pipe.
If you are piping into an argument that is not last, it means that you are breaking this regularity, so you are no longer passing one data structure through a series of transformations. This will make your code confusing because "it looks like a pipe, but it is not really a pipe".
Of course, this is not always the case and there are situations where you need this, but as a rule of thumb, I'd only use pipe when it fits.
Just use a lambda:
[1;2;3] |> fun l -> l # [4;5;6]
or point-free:
[1;2;3] |> (#) <| [4;5;6] // or
([1;2;3], [4;5;6]) ||> (#)
or as a normal function:
let foo l = l # [4;5;6]
let bar = foo [1;2;3]
After asking my coworker, he suggested:
[1;2;3]
|> List.append
<| [4;5;6]
// Result: [1;2;3;4;5;6]
If you have any other suggestions to an F# beginner like me, I would greatly appreciate your help. Thank you.
Related
My attempt to do this is here (forgive the for loop - I was just curious to see if this was possible):
let (|>>) a (b : ('a -> unit) list) =
for x in b do
x a
but when I try to use it I get the error
That None of the types error message can occur if the function you're trying to use is defined further down the file or isn't imported correctly. Otherwise, your function definition seems ok.
I would discourage the use of a custom operator for this. I think they should be used very rarely. This one doesn't seem general enough to be worth defining and could make code hard to read. Here is one alternative:
[ printf "%A"; printfn "%A" ] |> List.iter ((|>) 1)
But it's even clearer and shorter to write out your operator definition inline:
for f in [ printf "%A"; printfn "%A" ] do f 1
I have already done some searches, and this question is a duplicate of another post. I am posting this just for future reference.
Is it possible to define SUMPRODUCT without explicitly using variable names x, y?
Original Function:
let SUMPRODUCT x y = List.map2 (*) x y |> List.sum
SUMPRODUCT [1;4] [3;25] // Result: 103
I was hoping to do this:
// CONTAINS ERROR!
let SUMPRODUCT = (List.map2 (*)) >> List.sum
// CONTAINS ERROR!
But F# comes back with an error.
I have already found the solution on another post, but if you have any suggestions please let me know. Thank you.
Function composition only works when the input function takes a single argument. However, in your example, the result of List.map2 (*) is a function that takes two separate arguments and so it cannot be easily composed with List.sum using >>.
There are various ways to work around this if you really want, but I would not do that. I think >> is nice in a few rare cases where it fits nicely, but trying to over-use it leads to unreadable mess.
In some functional languages, the core library defines helpers for turning function with two arguments into a function that takes a tuple and vice versa.
let uncurry f (x, y) = f x y
let curry f x y = f (x, y)
You could use those two to define your sumProduct like this:
let sumProduct = curry ((uncurry (List.map2 (*))) >> List.sum)
Now it is point-free and understanding it is a fun mental challenge, but for all practical purposes, nobody will be able to understand the code and it is also longer than your original explicit version:
let sumProduct x y = List.map2 (*) x y |> List.sum
According to this post:
What am I missing: is function composition with multiple arguments possible?
Sometimes "pointed" style code is better than "pointfree" style code, and there is no good way to unify the type difference of the original function to what I hope to achieve.
Coming from an OO background, I am having trouble wrapping my head around how to solve simple issues with FP when trying to avoid mutation.
let mutable run = true
let player1List = ["he"; "ho"; "ha"]
let addValue lst value =
value :: lst
while run do
let input = Console.ReadLine()
addValue player1List input |> printfn "%A"
if player1List.Length > 5 then
run <- false
printfn "all done" // daz never gunna happen
I know it is ok to use mutation in certain cases, but I am trying to train myself to avoid mutation as the default. With that said, can someone please show me an example of the above w/o using mutation in F#?
The final result should be that player1List continues to grow until the length of items are 6, then exit and print 'all done'
The easiest way is to use recursion
open System
let rec makelist l =
match l |> List.length with
|6 -> printfn "all done"; l
| _ -> makelist ((Console.ReadLine())::l)
makelist []
I also removed some the addValue function as it is far more idiomatic to just use :: in typical F# code.
Your original code also has a common problem for new F# coders that you use run = false when you wanted run <- false. In F#, = is always for comparison. The compiler does actually warn about this.
As others already explained, you can rewrite imperative loops using recursion. This is useful because it is an approach that always works and is quite fundamental to functional programming.
Alternatively, F# provides a rich set of library functions for working with collections, which can actually nicely express the logic that you need. So, you could write something like:
let player1List = ["he"; "ho"; "ha"]
let player2List = Seq.initInfinite (fun _ -> Console.ReadLine())
let listOf6 = Seq.append player1List list2 |> Seq.take 6 |> List.ofSeq
The idea here is that you create an infinite lazy sequence that reads inputs from the console, append it at the end of your initial player1List and then take first 6 elements.
Depending on what your actual logic is, you might do this a bit differently, but the nice thing is that this is probably closer to the logic that you want to implement...
In F#, we use recursion to do loop. However, if you know how many times you need to iterate, you could use F# List.fold like this to hide the recursion implementation.
[1..6] |> List.fold (fun acc _ -> Console.ReadLine()::acc) []
I would remove the pipe from match for readability but use it in the last expression to avoid extra brackets:
open System
let rec makelist l =
match List.length l with
| 6 -> printfn "all done"; l
| _ -> Console.ReadLine()::l |> makelist
makelist []
A real F# noob question, but what is |> called and what does it do?
It's called the forward pipe operator. It pipes the result of one function to another.
The Forward pipe operator is simply defined as:
let (|>) x f = f x
And has a type signature:
'a -> ('a -> 'b) -> 'b
Which resolves to: given a generic type 'a, and a function which takes an 'a and returns a 'b, then return the application of the function on the input.
You can read more detail about how it works in an article here.
I usually refer to |> as the pipelining operator, but I'm not sure whether the official name is pipe operator or pipelining operator (though it probably doesn't really matter as the names are similar enough to avoid confusion :-)).
#LBushkin already gave a great answer, so I'll just add a couple of observations that may be also interesting. Obviously, the pipelining operator got it's name because it can be used for creating a pipeline that processes some data in several steps. The typical use is when working with lists:
[0 .. 10]
|> List.filter (fun n -> n % 3 = 0) // Get numbers divisible by three
|> List.map (fun n -> n * n) // Calculate squared of such numbers
This gives the result [0; 9; 36; 81]. Also, the operator is left-associative which means that the expression input |> f |> g is interpreted as (input |> f) |> g, which makes it possible to sequence multiple operations using |>.
Finally, I find it quite interesting that pipelining operaor in many cases corresponds to method chaining from object-oriented langauges. For example, the previous list processing example would look like this in C#:
Enumerable.Range(0, 10)
.Where(n => n % 3 == 0) // Get numbers divisible by three
.Select(n => n * n) // Calculate squared of such numbers
This may give you some idea about when the operator can be used if you're comming fromt the object-oriented background (although it is used in many other situations in F#).
As far as F# itself is concerned, the name is op_PipeRight (although no human would call it that). I pronounce it "pipe", like the unix shell pipe.
The spec is useful for figuring out these kinds of things. Section 4.1 has the operator names.
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html
Don't forget to check out the library reference docs:
http://msdn.microsoft.com/en-us/library/ee353754(v=VS.100).aspx
which list the operators.
Which of theese two alternatives do you find yourself using most often, and which is more "idiomatic"?
f arg (obj.DoStuff())
f arg <| obj.DoStuff()
Overall, I don't know that one or the other is more idiomatic.
Personally, the only time I use <| is with "raise":
raise <| new FooException("blah")
Apart from that, I always use parens. Note that since most F# code uses curried functions, this does not typically imply any "extra" parens:
f arg (g x y)
It's when you get into non-curried functions and constructors and whatnot that it starts getting less pretty:
f arg (g(x,y))
We will probably at least consider changing the F# languages rules so that high-precedence applications bind even more tightly; right now
f g()
parses like
f g ()
but a lot of people would like it to parse as
f (g())
(the motivating case in the original question). If you have a strong opinion about this, leave a comment on this response.
Because type inference works from left to right, a bonus of using |> is that it allows F# to infer the type of the argument of the function.
As a contrived example,
[1; 2; 3] |> (fun x -> x.Length*2)
works just fine, but
(fun x -> x.Length*2) [1; 2; 3]
complains of "lookup on object of indeterminate type".
I use () much much more often, but thats just preference, I'm pretty sure that <| is more idomatic, but I use () by habit.
Whenever possible, I much prefer |> because it reads from left to right.