Computational Expression with Generics
f#, generics
Solution
The problem isn't the lack of higher kinds, it's the value restriction: you can't define `state` as a generic value of type `StateMonadBuilder<World<'a,'b,'c'>>`. Since `state` is pure, the one-line fix is to make `state` a type function instead:
let state<'a,'b,'c> = StateMonadBuilder<World<'a, 'b, 'c>> ()
As to the problem with `World<int,int,int>(10,20,30)` - the type `World` can take generic arguments, but the union case can't. Since the type is fully determined by the constructor's arguments, it will be inferred if you drop the arguments, but you can also add a type annotation if you want to be sure: `(World(10,20,30) : World<int,int,int>)`
Problem
I am struggling troubleshooting this generic expression: ``` type World<'a, 'b, 'c> = World of 'a * 'b * 'c type StateFunc<'State, 'T> = 'State -> 'T * 'State type StateMonadBuilder<'State>() = // M<'T> -> M<'T> member b.ReturnFrom a : StateFunc<'State, 'T> = a // 'T -> M<'T> member b.Return a : StateFunc<'State, 'T> = ( fun s -> a, s) // M<'T> * ('T -> M<'U>) -> M<'U> member b.Bind(p : StateFunc<_, 'T>, rest : 'T -> StateFunc<_,_>) : StateFunc<'State, 'U> = (fun s -> let a, s' = p s rest a s') // Getter for the whole state, this type signature is because it passes along the state & returns the state member b.get : StateFunc<'State, _> = (fun s -> s, s) // Setter for the state member b.put (s:'State) : StateFunc<'State, _> = (fun _ -> (), s) let state = StateMonadBuilder<World<'a, 'b, 'c>> () let set1 a = state { let! World(_, b, c) = state.get do! state.put(World(a, b, c)) } let set2 b = state { let! World(a, _, c) = state.get do! state.put(World(a, b, c))} let testfun<'a, 'b> (one:'a) (two:'b) : StateFunc<World<'a, 'b, _>, _> = state { let! World(a,b,c) = state.get do printfn "%A" a do printfn "%A" b do printfn "%A" c do printfn "%A" "---------------------------" do! set1 one do! set2 two let! World(a,b,c) = state.get do printfn "%A" a do printfn "%A" b do printfn "%A" c do! state.put(World(a, b, c)) } let appliedTest = testfun<int,int> 10 20 let result = appliedTest (World<int, int, int>(10, 20, 30)) ``` The goal is to have a generic state monad that carries forward `World`, a tri-tuple. The compiler reports an error for `testfun<'a, 'b> (one:'a) (two:'b)` error FS0670: This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope. Furthermore, `World<int, int, int>(10, 20, 30)` claims that the type parameters are unexpected, which is surprising me. I suppose the problem is actually with `let state = StateMonadBuilder<World<'a, 'b, 'c>> ()`, in other words I am not supposed to initialized the state builder with a generics. Thanks! EDIT I think that what I am trying to do is prevented by the lack of higher kinded-types: http://cs.hubfs.net/topic/None/59392