Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anything *else* similar to Haskell's $ in F# other than <|?

Tags:

f#

I know there's the back-pipe (<|) operator, referenced in several other SO answers. But that doesn't work well when combined with forward pipes (|>), which is common in chaining. However I'm looking for related options. Basically is there any built-in version of the below function definition? Or is this a bad/dangerous practice?

let inline (^%) f = f

let stuff = 
  [1;2;3]
  |> Seq.filter ^% (>) 2
  |> Seq.map ^% fun x -> x.ToString()


// compare to this, which doesn't compile (and would be hard to follow even if it did)
let stuff = 
  [1;2;3]
  |> Seq.filter <| (>) 2
  |> Seq.map <| fun x -> x.ToString()
like image 537
Dax Fohl Avatar asked Mar 25 '16 12:03

Dax Fohl


1 Answers

There are some Haskell features, like optional infixing using backticks, and sections, which aren't available in F#. That makes certain constructs a bit more verbose.

Usually, I'd simply write a pipe of functions as the above like this:

let stuff = 
  [1;2;3]
  |> Seq.filter (fun x -> x < 2)
  |> Seq.map string

This is, in my opinion, much more readable. For example, using Seq.filter ^% (>) 2, I'd intuitively read that as meaning 'all values greater than 2', but that's not what it does:

> let inline (^%) f = f;;

val inline ( ^% ) : f:'a -> 'a

> let stuff = 
  [1;2;3]
  |> Seq.filter ^% (>) 2
  |> Seq.map ^% fun x -> x.ToString()
  |> Seq.toList;;

val stuff : string list = ["1"]

If you leave the reader of the code in doubt of what the code does, you've just made everyone less productive. Using Seq.filter (fun x -> x < 2) may look more verbose, but is unambiguous to the reader.

like image 177
Mark Seemann Avatar answered Nov 07 '22 23:11

Mark Seemann