我有一个函数片段:
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)]
答案 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' f
或flip 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)]