首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以Do-notation - Haskell返回一些值。

以Do-notation - Haskell返回一些值。
EN

Stack Overflow用户
提问于 2015-04-10 17:34:43
回答 2查看 71关注 0票数 0

我已经了解了do-notation。现在我想开发一个函数,它转换一个列表。

我希望它表现得像这样:

代码语言:javascript
复制
λ> transform 42 [1, 2, 3, 4, 5, 6]
[1, 42, 2, 42, 3, 42, 4, 42, 5, 42, 6, 42]

我目前的代码是:

代码语言:javascript
复制
transform :: a -> [a] -> [a]
transform new_number xs = do x <- xs
                            return x
                            return new_number

...and我的结果是:

代码语言:javascript
复制
λ> transform 42 [1, 2, 3]
[42,42,42]

我怎么才能解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-10 17:48:47

return在Haskell中的工作方式与命令式语言不同。在这里编写两个return没有意义,因为第二个“覆盖”了第一个。

do-notation专门用于处理Monad,因此您有一个正确的类型,但是您使用的函数不正确。我就是这样做的:

代码语言:javascript
复制
transform :: a -> [a] -> [a]
transform new xs = do
  x <- xs
  [x,new]

这是有效的原因是我用[a]类型的东西结束我的表达式。您不必一定要使用return

在这里使用do-notation有点混乱,所以最好使用concatMap :: (a -> [b]) -> [a] -> [b]

代码语言:javascript
复制
transform new xs = concatMap (\x -> [x,new]) xs
票数 5
EN

Stack Overflow用户

发布于 2015-04-10 17:47:38

要使用monad列表,monad列表中的return意味着“将值添加到monad上下文”或代码中。

代码语言:javascript
复制
do x <- xs
   return x

等于

代码语言:javascript
复制
do x <- xs
   [x]

因此,转换函数应该类似于

代码语言:javascript
复制
tranform :: a -> [a] -> [a]
tranform new_number xs = do x <- xs
                            x: [new_number]

这相当于

代码语言:javascript
复制
tranform new_number xs = concatMap (:[new_number]) xs

do表示法对

代码语言:javascript
复制
xs >>= \x -> x:[new_number]

单列表的绑定运算符与concatMap相关。

代码语言:javascript
复制
concatMap :: (a -> [b]) -> [a] -> [b]
(>>=) :: Monad m => m a -> (a -> m b) -> m b

在本例中,m a是单一列表[] a

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29567447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档