Haskell中的liftM和mapM有什么区别
liftM和mapM的功能有什么区别?首先,类型不同:Haskell中的liftM和mapM有什么区别,haskell,functional-programming,monads,combinators,Haskell,Functional Programming,Monads,Combinators,liftM和mapM的功能有什么区别?首先,类型不同: liftM :: (Monad m) => (a -> b) -> m a -> m b mapM :: (Monad m) => (a -> m b) -> [a] -> m [b] liftM将类型为a->b的函数提升为一元对应函数。 mapM将一个函数应用于一个值列表,该函数生成一个一元值,并生成嵌入一元值的结果列表 示例: > liftM (map toUpper) getLi
liftM :: (Monad m) => (a -> b) -> m a -> m b
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
liftM
将类型为a->b
的函数提升为一元对应函数。
mapM
将一个函数应用于一个值列表,该函数生成一个一元值,并生成嵌入一元值的结果列表
示例:
> liftM (map toUpper) getLine
Hallo
"HALLO"
> :t mapM return "monad"
mapM return "monad" :: (Monad m) => m [Char]
。。。请注意,map
和mapM
不同!例如
> map (x -> [x+1]) [1,2,3]
[[2],[3],[4]]
> mapM (x -> [x+1]) [1,2,3]
[[2,3,4]]
他们并没有真正的联系。我会尽力解释他们每个人都做了什么。我想你对单子有一个基本的了解
liftM::Monad m=>(a->b)->(ma->mb)
允许您在Monad中使用普通函数。它接受一个函数a->b
,并将其转换为一个函数ma->mb
,该函数的作用与原始函数完全相同,但它是在单子中完成的。结果函数不会对monad“做”任何事情(它不能,因为原始函数不知道它在monad中)。例如:
main :: IO ()
main = do
output <- liftM ("Hello, " ++) getLine
putStrLn output
这张照片是:
1
2
3
[(),(),()]
它所做的是迭代列表,对列表中的每个元素应用
(putStrLn.show)
(具有打印每个数字的IO效果),并将数字转换为()
值。结果列表由[(),(),()]
--putStrLn的输出组成。其他答案已经很好地解释了这一点,因此我只想指出,在真实的Haskell代码中,通常会看到使用fmap
而不是liftM
,asfmap
只是类型类Functor
中更通用的版本。由于所有行为良好的Monad
s都应该是Functor
的实例,它们应该是等价的
您还可以看到操作员
用作fmap
的同义词
另外,
mapM f=序列。映射f,因此您可以将其视为将值列表转换为操作列表,然后依次运行操作,将结果收集到列表中。liftM
和mapM
非常不同,从它们的类型和实现可以看出:
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f as = sequence (map f as)
liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
liftM f m1 = do { x1 <- m1; return (f x1) }
mapM::Monad m=>(a->mb)->[a]->m[b]
mapM f as=序列(map f as)
liftM::(单子m)=>(a1->r)->M1->MR
liftM f m1=do{x1@larsmans,这个问题与mapM无关。@mgiuca:你说得对。对不起,我想我应该仔细阅读。此外,如果你只关心mapM
的一元效应,而不关心返回的列表,你可以使用mapM
。mapM
函数的类型是Monad m=>(a->mb)->[a]->m()
,它在putStrLn示例中很有用,您可能对单位列表不感兴趣。@Tom Lokhorst Yep,没错。(我找不到一个有用的示例,结果对IO monad很重要。)为什么mapM会将数字转换为“()”?@Luke theputStrLn::String->IO()
返回一个单位值(即()
)。下面是另一个示例:mapM(\x->putStrLn(show x)>>返回(x+1))[1,2,3]
。这将返回一个整数列表而不是单位。它是(\x->[x+1])
在lambda for map中?我尝试了不带反斜杠的x语法,在表达式上下文中得到了模式语法:x->[x+1]
。我是Haskell新手,所以我可能在这里遗漏了一些东西。
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f as = sequence (map f as)
liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
liftM f m1 = do { x1 <- m1; return (f x1) }