This is a real quick and simple thing, so uh yeah… One of the things I detest in F# is having to use the “normal” method chaining built into C#. FOr instance with the StringBuilder class:
open System.Text let something = StringBuilder() .Append("hi") .Append("there") .Append("!") .ToString()
Now for C# that is acceptable.. but not for F# when the |> operator is involved. I want this:
let something = StringBuilder() |> Append "Hi" |> Append "There" |> Append "!" |> ToString()
Which is actually a lot easier than it might seem. When using the |> the next method has to take in the last method’s result. As long as the last parameter of the method matches up with the result of the last, you’re gold. This will NOT work:
let something = StringBuilder() |> Append "Hi"
There’s no StringBuilder to be used for that Append method, so it breaks. Remember, the last parameter of the next method has to be the same as the preceding result. So…:
let append (text: string) (builder : StringBuilder) = builder.Append(text) let toString (builder : StringBuilder) = builder.ToString()
As you can see, the appendBuiler method has a signature of StringBuilder -> string -> StringBuilder meaning it takes in a string and then a StringBuilder. Now because of currying, this is complete viable:
appendBuidler "Hi" ?
Where the ? will be filled in at some point. All it knows is that the ? will be a StringBuilder. With this in mind, the chain kind of looks like this:
StringBuilder() |> append "Hi" ? |> append "There" ? |> append "!" ? |> toString ?
Where every ? is a place holder for the result of the previous method.
Does this save any time? Eh probably not. However, it does show the how useful the |> can be when it comes to workflow like design. For example:
database |> openAConnection |> getAllUserNames |> closeTheConnection |> Seq.length > 0 |> shouldBeTrue
See if you can figure that one out.