带有monads的{Haskell中的表达式结果

时间:2016-12-11 23:18:29

标签: haskell monads

我目前正准备参加关于Haskell的期末考试,我正在考虑Monads,我们举了一个例子:

给出List Monad的以下定义:

instance Monad [] where
  m >>= f = concatMap f m
  return x = [x] 

其中(>>=)concatMap的类型为

 (>>=) :: [a] -> (a -> [b]) -> [b]
 concatMap :: (a -> [b]) -> [a] -> [b]

表达式的结果是什么?

> [1,2,3] >>= \x -> [x..3] >>= \y -> return x
  [1, 1, 1, 2, 2, 3] //Answer

这里的答案与我的想法不同,现在我们简要地介绍了Monads,但是根据我的理解(>>=)被称为bind,可以在上面的表达式中读作“applyMaybe”。在这种情况下,对于绑定的第一部分,我们得到[1,2,3,2,3,3],我们继续绑定的第二部分,但return x被定义为返回x的列表。应该是[1,2,3,2,3,3]。但是,我可能误解了这个表达方式。任何人都可以解释我的方法的错误做法,我应该如何解决这个问题。谢谢。

2 个答案:

答案 0 :(得分:2)

  

这种情况对于绑定的第一部分我们得到[1,2,3,2,3,3]

正确。

  

我们继续绑定的第二部分,但是“return x”被定义为返回x的列表。应该是[1,2,3,2,3,3]。

请注意,......

[1,2,3] >>= \x -> [x..3] >>= \y -> return x

... x由第一个(>>=)的(lambda)绑定,而不是第二个[1,2,3] >>= (\x -> [x..3] >>= (\y -> return x)) 。一些额外的括号可能会更清楚:

\y -> return x

y中,绑定到[1,2,3,2,3,3]的值(即x的元素)将被忽略,并被绑定到y的相应值替换(是,生成每个[1, 2, 3] -- [1,2,3] [1,2,3, 2,3, 3] -- [1,2,3] >>= \x -> [x..3] [1,1,1, 2,2, 3] -- [1,2,3] >>= \x -> [x..3] >>= \y -> return x 的原始列表的元素。原则上,我们有:

<UI>
        <TextStyle Id="White12" FaceName="Tahoma" Size="12" Red="255" Green="255" Blue="255"  />
        <UIRef Id="WixUI_InstallDir" />
        ...
</UI>

答案 1 :(得分:1)

首先,让我们清楚这个表达式是如何被解析的:lambdas是语法预示,即他们尽可能多地抓住它们,使用它作为函数结果。所以你在那里解析为

[1,2,3] >>= (\x -> ([x..3] >>= \y -> return x))

内部表达式实际上写得比它应该更复杂。完全不使用y,而a >>= \_ -> p只能写为a >> p。但是有一个更好的替代品:通常,monadic bind a >>= \q -> return (f q)等同于fmap f a,所以你的表达式应该真的写成

[1,2,3] >>= (\x -> (fmap (const x) [x..3]))

[1,2,3] >>= \x -> map (const x) [x..3]

[1,2,3] >>= \x -> replicate (3-x+1) x

此时应该非常清楚结果是什么,因为列表monad中的>>=只是映射每个元素并连接结果。