2012-02-24 66 views
3

內構建我有這個片段的函數:哈斯克爾:一元lambda函數

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

隨着

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

它可以作爲預期,但我不喜歡IO構建withing拉姆達。 它如何寫成不同? 我剛剛從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

什麼是「IO結構」? – newacct 2012-02-24 04:53:46

+0

題外話:在stackoverflow上,接受答案通常被認爲是禮貌的(點擊答案評分下面的勾),這有助於你解決問題。它不僅可以幫助回答問題的用戶,還可以幫助您,因爲它爲其他用戶提供瞭解決問題的動力。 – Vitus 2012-02-24 13:17:46

回答

4

我建議liftM<$>

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

非常感謝。我實際上在幾秒前就已經明白了這一點。我用liftM完成了你的建議。它解決了:mapM(\ x - > liftM(strSwop「if0」(「if」++ show x))t)[0 ..(n-1)] – 2012-02-24 03:12:26

+1

@r。sendecky:如果答案對你有幫助,你應該點擊它下面的複選標記來接受它:) – ehird 2012-02-24 07:26:35

2

讓我們簡化代碼一步一步來。

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

開始通過斷開的純代碼 - 讓我們用鑽營轉換[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)] 
+0

太棒了! :) 非常感謝你。 – 2012-02-24 03:50:49