关于函数monad [英] About the function monad

查看:93
本文介绍了关于函数monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对函数monad有些疑惑。 monad函数定义如下:
$ b $ pre $ instance Monad(( - >)r)其中
return x = \_ - > x
h>> = f = \ w - > f(hw)w

我试图通过编写绑定操作来解决它:

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

(返回3): :(( - >)Int)

但它导致错误。我还尝试将一个AddStuff函数重写到绑定操作中。

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



<然后将这个函数转换为

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

$ b

我检查新函数的类型,参见

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

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

解决方案

addStuff' code>(* 2)w 和(+ 10)w 。这些分别相当于 w * 2 w + 10 。所以 addStuff'等价于:

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

用这种方式写下来应该很明显,左操作数为>> = 是数字,而不是函数。这就是为什么推断类型告诉你,你的函数只适用于单数的数字。



当消除 do 注释到>> = 的左操作数应该与< - 的右操作数完全相同。同样消除 do notation不会为该函数添加任何参数。因此,正确的重写将如下所示:

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






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

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

运算符>> = 键入 ma - > (a - > m b) - > m b 。为了简单起见,我们假设这段代码中的所有数字都有类型 Int ,那么你的左操作数的类型为 Int - >如果 m ( - >),则或 m Int )Int 。因此,对于某些类型 b ,右操作数应该有类型 Int - > (( - >)Int)b 或者更可读地, Int→> Int - > B'/ code>。它实际具有的类型是 Int - > INT 。因此你的表达是不正确的。

 (return 3)::(( - >)int)

(( - >)Int) has kind * - > * - 值的类型必须是 *



这有些不同: return 3 对于某些 m m Int >(为了简单起见,仍假设所有整数文字都有类型 Int )。因此,如果 m `(( - >)Int),则的类型返回3 将是(( - >)Int)Int Int - > Int ,而不是(( - >)Int)


I have some confusion with the function monad. The function monad is defined as follow:

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

I tried to play around with it by writing a binding operation:

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

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

But it caused errors. And I also try to rewrite a function AddStuff into the binding operations.

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

then convert this function into

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

I check the type of the new function as see

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

Why is that? How can I fix that?

解决方案

In addStuff' you write (*2) w and (+10) w. Those are equivalent to w*2 and w+10 respectively. So addStuff' is equivalent to this:

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

Writing it this way should make it obvious that here the left operands to >>= are numbers, not functions. That's why the inferred type is telling you that your function only works for numbers that are monads.

When eliminating do notation the left operand to >>= should be exactly the same as the right operand of <-. Also eliminating do notation does not add any arguments to the function. So the correct rewriting would look like this:

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


As to why your earlier pieces of code don't work:

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

The operator >>= has type m a -> (a -> m b) -> m b. For simplicity let's assume that all the numbers in this code have type Int, then your left operand has type Int -> Int or m Int if m is (->) Int. So for some type b the right operand should have type Int -> ((->) Int) b or, more readably, Int -> Int -> b. The type it actually has though is Int -> Int. Therefore your expression is ill-typed.

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

((->) Int) has kind * -> * - the type of a value must have kind *.

Or to approach this differently: return 3 has type m Int for some m (still assuming that all integer literals have type Int for simplicity). So if m is `((->) Int), the type of return 3 will be ((->) Int) Int or Int -> Int, not ((->) Int).

这篇关于关于函数monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆