gpt4 book ai didi

haskell - 如何在 Elm 中结合结果和状态?

转载 作者:行者123 更新时间:2023-12-04 18:58:52 24 4
gpt4 key购买 nike

我正在为 Elm 缺乏单子(monad)而苦苦挣扎。为 Elm ( http://package.elm-lang.org/packages/folkertdev/elm-state/latest/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))
)

最佳答案

Can someone who is familiar with Haskell monad transformers explain how they solve this kind of problem or suggest an alternative solution?



好吧,我至少可以试试。这是您的类型直接转换为 Haskell 的样子:
type EffM a s x = Either a (State s x)

一个相当明显的观察结果是它不是一个单子(monad)变压器。2 这就是一个变压器的样子:
type TransM a s x = EitherT a (State s) x

如您所见,唯一的变化是 T以及 x 的事实在括号之外。后一部分对于理解变压器方法至关重要。

核心思想是 State是结果产生的一部分,无论 Either导致“成功”或“失败”,而在你的情况下产生“失败”意味着状态操作从未被触及。我需要更加努力地思考这在实践中意味着什么,但直观地说,在使用典型的命令式代码时,你会想到转换器方法。

现在,当你使用这样的变压器时, join由于适合 Monad 接口(interface),实际上是免费提供的。
import Control.Monad.State
import Control.Monad.Trans.Either
import Control.Monad

type Eff e s a = EitherT e (State s) a

-- type the following in REPL

λ :t join
join :: Monad m => m (m a) -> m a

λ :t join :: Eff e s (Eff e s a) -> Eff e s a
join :: Eff e s (Eff e s a) -> Eff e s a
:: Eff e s (Eff e s a) -> Eff e s a

-- the slightly cryptic output above means that it typechecks correctly

所以这就是 Haskell1 解决它的方法。现在,显然可以编写一个专门的 EitherState以这种方式输入(尽管我个人将所有示例中的这两个翻转为 StateEither - 感觉更自然),反射(reflect)了 join 的实现对于各自的变压器会做。不知道有没有写 EitherT特别是在榆树中是可能的。

1 一种可能的方法。还有其他递归方案/免费可能是 future 几年值得关注的方案。效果堆叠的固有顺序结果比最初看起来更成问题。

2 它也不是 Monad ,至少在 x 的意义上不能是 Monad 实例中的直接类型(因为 Either 在特殊情况下显然可以充当一种)。

关于haskell - 如何在 Elm 中结合结果和状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43065473/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com