简体   繁体   中英

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

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()

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM