Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 关于单子函数_Haskell_Monads - Fatal编程技术网

Haskell 关于单子函数

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

我对monad函数有些混淆。函数monad的定义如下:

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)