I'm fighting with a few pathetic lines of code but cannot wrap my head around the problem - for whatever reason I can't get under the principle of this aspect of F#'s type system and so far all my reading hasn't worked.
Can anyone point out to me the rather stupid schoolboy error I'm making here? I know I am making one, I just cannot see it! I'm trying to climb out of painful beginner land on this, so grokking the full principle of why this doesn't work is my aim - any help would be gratefully received!
It's a simple exercise - just a practice one actually that doesn't really need a monad to perform, however I really want these things under my belt for my next project.
let stringToInt str = Int32.TryParse(str)
type wk() =
member this.Bind(f , str) = f str
member this.Return(f ) = f
let strInt = new wk()
let test a = strInt{let! b = strInt.Bind a stringToInt
return b}
let x = test "10"
printfn "%s" x
I'm getting the following:
Program.fs(117,14): error FS0001: This expression was expected to have type
(string -> bool * int) -> ('a -> 'a) -> 'b
but here has type string
Update: Based on help from below, I have this working now:
open System
open System.Threading
let stringToInt str = snd <| Int32.TryParse(str)
type wk() =
member this.Bind(funct, str) = funct str
member this.Return(str) = str
let strInt = new wk()
//Jack P syntax!
let test2 str funct = strInt{
let! b = funct str
return b
}
let go2 = test2 ("10", stringToInt) |> printfn "%A"
Though working is perhaps still not conceptually there yet - getting the value to print doesn't happen. I'll keep hacking through - I've done tons of reading, that's where I got the exercise from but the only way I'll get the concept is to continue to fight with it I think.
I succeeded in a simpler form on my blog: http://richardgriffiths.azurewebsites.net/?p=2332 so I just need to bust the syntax/concept barrier I've got with the type system.
You've defined
Bind
to take a tupled argument (which is correct for a computation builder), but you're passing the arguments in curried form (strInt.Bind a stringToInt
instead ofstrInt.Bind(a, stringToInt)
).