【发布时间】:2013-11-25 13:40:35
【问题描述】:
我正在努力解决这个通用表达式:
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))
目标是拥有一个继承World 的通用状态单子,一个三元组。
编译器报错testfun<'a, 'b> (one:'a) (two:'b)
错误 FS0670:此代码不够通用。类型变量 'a 无法泛化,因为它会超出其范围。
此外,World<int, int, int>(10, 20, 30) 声称类型参数是出乎意料的,这让我很惊讶。
我想问题实际上出在let state = StateMonadBuilder<World<'a, 'b, 'c>> (),换句话说,我不应该用泛型初始化状态构建器。
谢谢!
编辑 我认为我正在尝试做的事情是由于缺乏更高的种类而被阻止:http://cs.hubfs.net/topic/None/59392
【问题讨论】: