Haskell 关于单子函数
我对monad函数有些混淆。函数monad的定义如下:Haskell 关于单子函数,haskell,monads,Haskell,Monads,我对monad函数有些混淆。函数monad的定义如下: instance Monad ((->) r) where return x = \_ -> x h >>= f = \w -> f (h w) w 我试图通过编写一个绑定操作来处理它: ( (*2) >>= (+10) ) 3 (return 3) :: ((->) Int) 但它导致了错误。我还尝试将函数AddStuff重写到绑定操作中 addStuff = d
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
我试图通过编写一个绑定操作来处理它:
( (*2) >>= (+10) ) 3
(return 3) :: ((->) Int)
但它导致了错误。我还尝试将函数AddStuff重写到绑定操作中
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
我检查新函数的类型,如所示
addStuff :: (Monad m, Num (m b), Num b) => m b -> m b
为什么呢?我如何解决这个问题?在
addStuff'
中,您编写(*2)w
和(+10)w
。这些分别相当于w*2
和w+10
。所以addStuff'
相当于:
addStuff' w = w*2 >>= \a ->
w+10 >>= \b ->
return (a+b)
以这种方式编写应该可以清楚地看到,这里>=
的左操作数是数字,而不是函数。这就是为什么推断类型告诉您,您的函数只适用于单子数
消除do
表示法时,>=
的左操作数应与Int
或m Int
的右操作数完全相同,如果m
是(>)Int
。因此,对于某些类型b
来说,正确的操作数应该具有类型Int->((->)Int)b
,或者更容易理解的是,Int->Int->b
。但它实际拥有的类型是Int->Int
。因此,您的表达式类型不正确
(return 3) :: ((->) Int)
((->)Int)
具有种类*->*
-值的类型必须具有种类*
或者换一种方法:
return 3
对于某些m
具有类型m Int
(为了简单起见,仍然假设所有整数文本都具有类型Int
)。因此,如果m
是((>)Int)
,那么返回3
的类型将是((>)Int
或Int->Int
,而不是(>)Int
,那么,你能解释一下((*2)>=(+10))3和(返回3):(((>)Int)@chipbk10我已经扩展了我的答案。((*2)>=(+10))如果num类有一个实例num b=>num(a->b)
,则3
将起作用,这在历史上是一个问题,但现在不再是了。您不应该使用
标记插入代码-这样您就不会得到语法突出显示。您应该使用四个空格的缩进或编辑工具栏上的“代码”按钮。@sepp2k:谢谢您提醒我。
addStuff' = (*2) >>= \a ->
(+10) >>= \b ->
return (a+b)
( (*2) >>= (+10) ) 3
(return 3) :: ((->) Int)