Generics 具有泛型的计算表达式
我正在努力排除这个通用表达式的故障:Generics 具有泛型的计算表达式,generics,f#,Generics,F#,我正在努力排除这个通用表达式的故障: 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
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))
type World()=
//M
成员b.ReturnFrom a:StateFunc=a
//'T->M*('T->M
成员b.Bind(p:StateFunc StateFunc):StateFunc=
(乐趣s->
设a,s'=ps
其余a(s)
//对于整个状态,这种类型的签名是因为它沿着状态传递&返回状态
成员b.get:StateFunc>()
设set1a=state{
让!World(u,b,c)=state.get
do!state.put(世界(a,b,c))}
设set2b=state{
让!World(a,u,c)=state.get
do!state.put(世界(a,b,c))}
让testfun(一:'a)(二:'b):StateFunc=state{
让!世界(a,b,c)=状态
是否打印fn“%A”A
是否打印fn“%A”b
是否打印fn“%A”c
是否打印fn“%A”-------------------------------------
开始!设定一
开始!第二局,第二局
让!世界(a,b,c)=状态
是否打印fn“%A”A
是否打印fn“%A”b
是否打印fn“%A”c
do!state.put(世界(a,b,c))}
让appliedTest=testfun 10 20
让结果=应用测试(世界(10,20,30))
我们的目标是拥有一个通用的状态单子,它继承了三元组World
。
编译器为testfun(一:'a)(二:'b)
错误FS0670:此代码不够泛型。无法泛化类型变量“a”,因为它将超出其作用域
此外,World(10,20,30)
声称类型参数是意外的,这让我感到惊讶
我想问题实际上在于
let state=StateMonadBuilder问题不是缺少更高的类型,而是:您不能将state
定义为类型为StateMonadBuilder
的泛型值。由于state
是纯的,因此一行修复方法是将state
改为:
let state<'a,'b,'c> = StateMonadBuilder<World<'a, 'b, 'c>> ()
let state>()
至于World(10,20,30)
的问题,类型World
可以接受泛型参数,但union案例不能。由于类型完全由构造函数的参数确定,因此如果删除参数,将推断出类型,但如果您想确定,也可以添加类型注释:(World(10,20,30):World)
太棒了,我不知道这让状态>()
是可能的!