Using bind and Kliesli composition operators with Result

Viewed 127

I'm trying to use the bind (>>=) and Kleisli composition (>=>) operators with the basic Result type, but either they are not defined or are not in scope:

let f x =
  if x%2 = 0 then Ok (x/2)
  else            Error ()

let ff x = Ok x >>= f >>= f
let ff' = f >=> f

[<EntryPoint>]
let main _ =
  printfn "%A" (ff 12)
  printfn "%A" (ff' 28)
  0

Error FS0043 Expecting a type supporting the operator '>>=' but given a function type. You may be missing an argument to a function.

I've tried to open a few different namespaces to bring the definition into scope, but no luck.

It seems from this like the operators can't be defined in general without extensions, but are there definitions for the standard Result anywhere?

2 Answers

Haskell-like operators are not defined in the F# core library, nor are they likely to ever be. You'll need to either write them in your own prelude, or use a library like FSharpPlus for these and other more Haskell-like (Well, typelevel) programming approaches.

In addition to what Phillip said in his answer, it might be useful to add that you can rewrite your example using the built-in Result.bind operation and function composition or piping:

let f x =
  if x%2 = 0 then Ok (x/2)
  else Error ()

let ff x = Ok x |> Result.bind f |> Result.bind f
let ff' = f >> Result.bind f

printfn "%A" (ff 12)
printfn "%A" (ff' 28)

This is of course just a toy example, so it's hard to say what you actually want to do, but if I was trying to use Result, my first choice would be to use the standard library functions - they may make your code longer, but it is arguably more readable.

Related