【发布时间】:2017-08-21 06:52:00
【问题描述】:
我正在为 Elm 缺乏单子而苦苦挣扎。为 Elm (http://package.elm-lang.org/packages/folkertdev/elm-state/latest/State) 实现 state monad 的库对我帮助很大。
问题是我现在遇到了交替嵌套 Result 和 State 类型的情况,而我只想拥有一个。
我尝试编写一个具有以下签名的函数,但这似乎是不可能的,因为只有在评估外部 State 后,才知道内部 Result。
join : Result a (State s (Result a (State s x))) -> Result a (State s x)
如果我将 Result 放在 State 中的返回值中,也许它会起作用,但如果外部 Result 是Err,那会生成一个虚拟状态。
我认为正确的想法是制作既是结果又是状态的东西。熟悉 Haskell monad 转换器的人能否解释一下他们如何解决此类问题或提出替代解决方案?
这里是出现问题的一个地方的粗略版本:
generateConstraints environment value
|> Result.map (State.map (\(value, valueC) ->
Result.map
(State.map2 (\this (body, bodyC) ->
( this
, valueC ++ bodyC ++ [(this, body)]
))
freshTypevar)
(generateConstraints (extend environment name value) body))
)
【问题讨论】:
-
当你混合相同类型的变压器时,Monad 变压器有点痛苦。我通常使用 monad 类型类,但是当类型出现多次时它们会失败。一个解决方案是新输入您需要的特定上下文。
-
我真的不需要多次使用同一个单子。我包含的代码 sn-p 是
generateConstraints的一种情况,它返回Result String (State Int (Type, List Constraint))。递归可以正常工作,但是对于 let 绑定的约束生成有一些不同之处,它会弄乱 monad。 -
我仍然不知道如何结合有状态和可能是错误的,但我给出的特定示例奇迹般地自行解决了,因为我能够将所有异常结果移出。
标签: haskell monads elm monad-transformers