gpt4 book ai didi

haskell - 尝试组合单子(monad)函数时出错

转载 作者:行者123 更新时间:2023-12-02 06:53:35 25 4
gpt4 key购买 nike

我刚刚了解了 monad,并且一直在尝试在 Control.Monad 中实现很多功能。我刚到 ap ,但我无法让它发挥作用。我做了一个函数 almostAp :: Monad m => m (a -> b) -> m a -> m (m b) ,我尝试将它与我制作的另一个函数 flatten :: Monad m => m (m b) -> m b 组合起来.问题是当我尝试使用 ap = flatten . almostAp 时, 我得到

Occurs check: cannot construct the infinite type: m ~ (->) (m a)
Expected type: m (a -> b) -> m a -> m a -> m b
Actual type: m (a -> b) -> m a -> m (m b)
In the second argument of ‘(.)’, namely ‘almostAp’
In the expression: (flatten . almostAp)`

但是,(flatten .)类型为 Monad m => (a -> m (m b)) -> a -> m b根据 ghci,为什么会发生这种情况?

这里是函数定义(我知道我可以用 =<< 和仿函数定律来清理它们):

almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
almostAp = (flip (\x -> fmap ($x))) . (fmap (flip (>>=))) . (fmap (return .))

flatten :: Monad m => m (m a) -> m a
flatten = (>>= id)

最佳答案

您遇到类型错误是因为您试图编写一个单参数函数flatten(顺便说一句,通常名称为 join )带有双参数函数almostAp(.)::(b -> c) -> (a -> b) -> (a -> c) 适用于右侧函数是单参数函数的情况。不幸的是,错误消息不是很有用。

(.).(.)(发音为“dot-dot-dot”,或“owl eyes”)做你想做的事想要:

ghci> let ap = ((.).(.)) flatten almostAp
ghci> :t ap
ap :: Monad m => m (a -> b) -> m a -> m b

但是 ap 可以用 do 符号更简单地实现。你的版本真的比这个更容易理解吗?

ap mf mx = do
f <- mf
x <- mx
return (f x)

do 符号只是 >>= 的语法糖。这是没有它的样子(尽管我更喜欢 do 版本):

ap mf mx = mf >>= \f -> fmap f mx

关于haskell - 尝试组合单子(monad)函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36536745/

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