gpt4 book ai didi

haskell - 定义自制 monad 变压器的绑定(bind)

转载 作者:行者123 更新时间:2023-12-02 11:58:56 24 4
gpt4 key购买 nike

我已经定义了我自己的 WriterT 版本以及一个解包函数:

newtype WT w m a = WT (m a, w)

unWT :: (Monoid w, Monad m) => WT w m a -> (m a, w)
unWT (WT cmaw) = cmaw

现在我尝试定义 monad (WT w m),但没有成功:

instance (Monoid w, Monad m) => Monad (WT w m) where
return x = WT (return x, mempty)
wtwma >>= fawtwmb = WT $ let (ma, w1) = unWT wtwma
(mb, w2) = unWT $ do a <- ma
fawtwmb a
in (mb, mappend w1 w2)

错误位于 do 表达式中,即我尝试从 ma 中提取 a 的位置:

Expected type: WT w m a, Actual type: m a

我尝试了一些变化,总是得到相似的结果。我无法为此 monad 定义 bind

我的主要问题是:如果单子(monad)位于一对内,我如何提取它的值?

最佳答案

想象一下以下计算:

tellLine :: WT String IO ()
tellLine = do
input <- WT (getLine, "")
WT (return (), input)

impossible :: String
impossible = snd (unWT tellLine)

如果这按“预期”工作,我们应该得到 impossible 是用户输入的字符串。但是,我们无法在 IO 之外执行此操作;这样的impossible不可能是一个纯粹的String,因为它在这里。因此不可能产生作为 monad 中的计算结果接收的 w

另一种可能性是简单地返回第一次绑定(bind)之前发生的w,因此我们不必依赖于任何单子(monad)操作。唉,其中一项身份法阻碍了我们。

return x >>= f = f x

在这里我们可以看到“在第一个绑定(bind)之前”不可能是一个有意义的概念,因为左边有一个绑定(bind),但右边没有。因此返回第一次绑定(bind)之前发生的 w 肯定会违反这个 monad 定律。

唯一剩下的可能性是w始终为mempty。但这也不起作用,因为有其他身份法则。

m >>= return = m

因此,如果 m 具有非 memptyw,则绑定(bind)将消除它并违反此定律。

这个WT不能是一个monad转换器。有一个WriterT转换器,但它被定义为m (a,w),这避免了这些问题。

关于haskell - 定义自制 monad 变压器的绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31392378/

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