Haskell:lambda函数中的Monadic构造

时间:2012-02-24 02:46:16

标签: haskell

我有一个函数片段:

mapM (\x -> do t' <- t; return $ strSwop "if0" ("if" ++ show x) t') [0..(n-1)]

使用

strSwop :: String -> String -> String -> String
t :: IO String

它按预期工作但我不喜欢带有lambda的IO构造。 如何以不同的方式写出来? 我走出monad只是为了再次包裹下一行。觉得难看。

如果我这样做:

mapM (\x -> t >>= strSwop "if0" ("if" ++ show x) t) [0..(n-1)]

它(显然)抱怨strSwop的返回签名:( strSwop只是一个字符串替换函数。 有没有办法正确写这个? 感谢。

- 编辑 -

刚想出来......

工作:

mapM (\x -> liftM (strSwop "if0" ("if" ++ show x)) t) [0..(n-1)]

2 个答案:

答案 0 :(得分:4)

我建议liftM<$>

import Control.Applicative
mapM (\x -> strSwop "if0" ("if" ++ show x) <$> t) [0..(n-1)]

答案 1 :(得分:2)

让我们一步一步地简化您的代码。

mapM (\x -> do t' <- t; return $ strSwop "if0" ("if" ++ show x) t') [0..(n-1)]

首先断开纯代码 - 让我们使用currying将[0..(n-1)]转换为[String -> String]列表:

mapM (\f -> do t' <- t ; return (f t)) $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

现在do t' <- t ; return (f t)很常见 - 只是fmap f t'

mapM (\f -> fmap f t') $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

\f -> fmap f t'只是\f -> flip fmap t' fflip fmap t'

mapM (flip fmap t') $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

清理纯半:\x -> strSwop "if0" ("if" ++ show x)\x -> strSwop "if0" $ ("if" ++) (show x)相同,与\x -> strSwop "if0" . ("if"++) $ show x相同,与strSwop "if0" . ("if"++) . show

相同
mapM (flip fmap t') $ map (strSwop "if0" . ("if"++ ) . show) [0..(n-1)]

现在让我们将这两个部分融合在一起。 mapM f . map g = sequence . map f . map g = sequence . map (f . g) = mapM (f . g)

mapM (flip fmap t' . strSwop "if0" . ("if"++) . show) [0..(n-1)]