2015-04-30 60 views
2

我有兩個功能:如何連接地圖函數中的列表 - Haskell?

fun1 :: Int -> [Int] 
fun2 :: [Int] -> [Int] 

fun2接受Int list和應用fun1到此列表中的每個元素的幫助map。但fun1返回[Int]。所以,我有類型衝突。如何解決我的問題?

+0

應該FUN2如下'FUN2 :: [INT] - > [INT]]' – PriestVallon

+1

此外,我不是很確定你想什麼去做?這只是爲了解決類型衝突嗎? – PriestVallon

+3

一個例子可以澄清查詢... – elm

回答

5

您可能需要mapconcat的組合來實現它。假設fun1fun2是這樣的:

fun1 :: Int -> [Int] 
fun1 x = [x,x] 

fun2 :: [Int] -> [Int] 
fun2 = map (+ 1) 

solution :: [Int] -> [Int] 
solution xs = concat $ map fun1 (fun2 xs) 

或者通過@CarstenKonig的建議,你可以使用concatMap

solution2 :: [Int] -> [Int] 
solution2 xs = concatMap fun1 $ fun2 xs 

可以進一步簡化爲:

solution2 :: [Int] -> [Int] 
solution2 = concatMap fun1 . fun2 
+1

基於「fun2接受Int列表並將fun1應用於此的每個元素」我認爲OP實際上只是想要'fun2 = concatMap fun1' - 但是這是另一個* type-checks *;) – Carsten

+1

@CarstenKönig我覺得這是O​​P的自然答案:)但是,我可能是錯的。 – Sibi

+1

這就是問題(不是你的答案) - 問題不是很好,但OP目前似乎無法澄清 – Carsten

3

的能力將[[a]]轉換爲[a]是使List(等等)成爲Monad的原因。 因此,您可以使用做記號:

fun2 xs = do 
    x <- xs 
    fun1 x 

可在改寫fun2 xs = xs >>= fun1甚至更​​好

fun2 = (>>= fun1) 
1

另一種方法是用列表理解。映射fun1在列表xs

fun2' xs = [ fun1 x | x <- xs ] 
    -- = map fun1 xs 
    -- = do x <- xs    -- for each x in xs: 
    --  return (fun1 x)  -- yield (fun1 x) 

這的確將有一個不同類型的比你想要的東西。

要弄平一步我們做

fun2 xs = [ y | x <- xs, y <- fun1 x ] 
    -- = concatMap fun1 xs 
    -- = do x <- xs    -- for each x in xs: 
    --  y <- fun1 x   -- for each y in (fun1 x): 
    --  return y    --  yield y