我已经了解了do-notation。现在我想开发一个函数,它转换一个列表。
我希望它表现得像这样:
λ> transform 42 [1, 2, 3, 4, 5, 6]
[1, 42, 2, 42, 3, 42, 4, 42, 5, 42, 6, 42]我目前的代码是:
transform :: a -> [a] -> [a]
transform new_number xs = do x <- xs
return x
return new_number...and我的结果是:
λ> transform 42 [1, 2, 3]
[42,42,42]我怎么才能解决这个问题?
发布于 2015-04-10 17:48:47
return在Haskell中的工作方式与命令式语言不同。在这里编写两个return没有意义,因为第二个“覆盖”了第一个。
do-notation专门用于处理Monad,因此您有一个正确的类型,但是您使用的函数不正确。我就是这样做的:
transform :: a -> [a] -> [a]
transform new xs = do
x <- xs
[x,new]这是有效的原因是我用[a]类型的东西结束我的表达式。您不必一定要使用return!
在这里使用do-notation有点混乱,所以最好使用concatMap :: (a -> [b]) -> [a] -> [b]
transform new xs = concatMap (\x -> [x,new]) xs发布于 2015-04-10 17:47:38
要使用monad列表,monad列表中的return意味着“将值添加到monad上下文”或代码中。
do x <- xs
return x等于
do x <- xs
[x]因此,转换函数应该类似于
tranform :: a -> [a] -> [a]
tranform new_number xs = do x <- xs
x: [new_number]这相当于
tranform new_number xs = concatMap (:[new_number]) xsdo表示法对
xs >>= \x -> x:[new_number]单列表的绑定运算符与concatMap相关。
concatMap :: (a -> [b]) -> [a] -> [b]
(>>=) :: Monad m => m a -> (a -> m b) -> m b在本例中,m a是单一列表[] a。
https://stackoverflow.com/questions/29567447
复制相似问题