In my quest to improve F # and better understand how Suave.io works, I tried to create some reusable functions / statements for composing functions. I understand that Suave actually implements its>>> operator to work specifically for the async option, but I thought it would be interesting for me to try and generalize it.
The code below is inspired by too many sources for lending, and it works well for types that I define myself, but I can't get it to work for system types. Although extensions like Nullable and Option compile fine, they are not recognized as matching member restrictions in the bind function.
When I was not able to get it to work for the option, I was hoping this could be due to the fact that the option was special in F #, so I tried using Nullable, but unfortunately no cigar.
The corresponding errors and the output from fsi are in the code below in the comment.
Any help would be appreciated.
Thanks, John
open System
let inline bind (f : ^f) (v : ^v) =
(^v : (static member doBind : ^f * ^v -> ^r )(f, v))
let inline (>=>) f g = f >> (bind g)
type public Result<'a,'b> =
| Success of 'a
| Error of 'b
type public Result<'a,'b> with
static member inline public doBind (f, v) =
match v with
| Success s -> f s
| Error e -> Error e
let rF a = if a > 0 then Success a else Error "less than 0"
let rG a = if a < 10 then Success a else Error "greater than 9"
let rFG = rF >=> rG
type Nullable<'T when 'T: (new : unit -> 'T) and 'T: struct and 'T:> ValueType> with
static member inline public doBind (f, v: Nullable<'T>) =
if v.HasValue then f v.Value else Nullable()
let nF a = if a > 0 then Nullable a else Nullable()
let nG a = if a < 10 then Nullable a else Nullable()
let nFG = nF >=> nG
type Core.Option<'T> with
static member inline doBind (f, v) =
match v with
| Some s -> f s
| None -> None
let oF a = if a > 0 then Some a else None
let oG a = if a < 10 then Some a else None
let oFG = oF >=> oG
// error FS0001: The type 'int option' does not support the operator 'doBind'
source
share