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)

太棒了,我不知道这
让状态>()
是可能的!