gpt4 book ai didi

haskell - 关于函数 monad

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

我对函数 monad 有一些困惑。函数monad定义如下:

instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w

我尝试通过编写绑定(bind)操作来尝试它:

( (*2) >>= (+10) ) 3 

(return 3) :: ((->) Int)

但是它导致了错误。我还尝试将函数AddStuff重写到绑定(bind)操作中。

addStuff = do
a <- (*2)
b <- (+10)
return (a+b)

然后将这个函数转换成

addStuff' w = (*2)  w >>= (\a ->
(+10) w >>= (\b ->
return (a+b) ))

我检查新函数的类型,如下所示

addStuff :: (Monad m, Num (m b), Num b) => m b -> m b 

这是为什么呢?我该如何解决这个问题?

最佳答案

addStuff'你写(*2) w(+10) w 。这些相当于 w*2w+10分别。所以addStuff'相当于这样:

addStuff' w = w*2 >>= \a ->
w+10 >>= \b ->
return (a+b)

这样写应该可以明显看出这里左边的操作数是 >>=是数字,不是函数。这就是为什么推断类型告诉您您的函数仅适用于作为 monad 的数字。

消除do时将左操作数表示为 >>=应该与 <- 的右操作数完全相同。还消除了do符号不会向函数添加任何参数。所以正确的重写应该是这样的:

addStuff' = (*2) >>= \a ->
(+10) >>= \b ->
return (a+b)
<小时/>

至于为什么你之前的代码不起作用:

( (*2) >>= (+10) ) 3 

运算符(operator)>>=类型为m a -> (a -> m b) -> m b 。为简单起见,我们假设此代码中的所有数字都具有类型 Int ,那么你的左操作数的类型为 Int -> Intm Int如果m(->) Int 。所以对于某些类型 b正确的操作数应为 Int -> ((->) Int) b 类型或者,更易读的是Int -> Int -> b 。它实际拥有的类型是 Int -> Int 。因此你的表达是错误的。

(return 3) :: ((->) Int)

((->) Int)有样* -> * - 值的类型必须有 kind * .

或者以不同的方式处理这个问题:return 3类型为m Int对于一些m (为了简单起见,仍然假设所有整数文字都具有类型 Int)。所以如果 m((->) Int) ,类型 return 3将是((->) Int) IntInt -> Int ,不是((->) Int) .

关于haskell - 关于函数 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14430397/

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