2016-11-27 60 views
2

我試圖在Haskell中實現類型爲Maybe [[Maybe a]] -> [[a]]的函數。我已經嘗試了多種方法,但我得到的最接近的是:如何實現'ex :: Maybe [[也許a]] - > [[a]]'方法

ex :: Maybe [[Maybe a]] -> [[a]] 
ex list = let l=list!!0 
      in []++(sequence l) 

這給了我以下錯誤:

Couldn't match expected type `[a0]' 
       with actual type `Maybe [[Maybe a]]' 
    In the first argument of `(!!)', namely `list' 
    In the expression: list !! 0 
    In an equation for `l': l = list !! 0 

我知道錯誤與第一個參數!!問題爭論不是一個正常的名單,但不能讓我的頭靠近它。

+1

輸入問題:「Maybe :: [[Maybe a]] - > [[a]]」應該是Maybe [[Maybe a]] - > [[a]]'。你也可以使用反引號(')作爲內聯代碼。 – jpath

+0

你想如何使用'ex'函數?你聲明'list'是一個'Maybe [[也許是]]',但你試圖通過應用'(!!)'' – Lee

+3

來嘗試把它當成一個列表。儘量不要使用像'(!!)',''頭「或」尾巴「。相反,模式匹配你的論點。它不僅是好的練習,它還將幫助你理解問題。你知道模式匹配嗎? – jpath

回答

3

一個可能的解決方案是:

ex = maybe [] (map catMaybes) 

方法:

一種方式來解決這樣的問題是遵循從最外層到最內層的類型,並且一路選擇適當的轉換功能。在這裏,我們將努力一步一步的修改對::左側的表情,直至其對正確的類型看起來像你想要的類型:

  1. 我們先從id作爲進一步轉換功能的佔位符,因爲它總是有正確的類型和什麼也不做:
    id :: a -> a

  2. 剝離外部Maybe。如果該值是Nothing,我們默認[]
    maybe [] id :: Maybe [a] -> [a]

  3. 我們要轉換的內[Maybe a][a]
    這可以與catMaybes :: [Maybe a] -> [a]的幫助來完成:
    maybe [] catMaybes :: Maybe [Maybe a] -> [a]

  4. 其實,我們要[[Maybe a]] -> [[a]]而非[Maybe a] -> [a]
    我們可以使用map :: (a -> a) -> [a] -> [a]更深層次的推動功能的一個級別到列表:
    maybe [] (map catMaybes) :: Maybe [[Maybe a]] -> [[a]]

工具:

  • 使用GHCI進行實驗。您可以通過:t命令詢問它的表達式類型,例如::t maybe [] id
  • 使用API​​搜索引擎來查找轉換函數。例如Hayoo或Hoogle。您可以輸入一個類型簽名作爲搜索查詢。例如,[Maybe a] -> [a]將返回catMaybes等。
1

看着簽名ex :: Maybe [[Maybe a]] -> [[a]]。你會想要做的第一件事是模式匹配你的參數的不同構造函數:

ex :: Maybe [[Maybe a]] -> [[a]] 
ex (Just list) = undefined 
ex Nothing = undefined 

所以有兩種情況我們必須處理。對於Nothing,您很可能只會返回[]。對於Just情況下,你可能會想擺脫所有的內部列表中Just元素:

ex :: Maybe [[Maybe a]] -> [[a]] 
ex (Just list) = catInnerMaybes list 
ex Nothing = [] 

catInnerMaybes :: [[Maybe a]] -> [[a]] 
catInnerMaybes (xs:xss) = undefined 
catInnerMaybes [] = undefined 

再次爲catInnerMaybes我們希望我們的參數,而不是使用像(!!)方法模式匹配。我將離開休息,你現在但這裏有一些更多的提示:

  • 嘗試使用:而不是++,因爲它是更自然,地道的方式用列表來工作,因爲++迅速得到緩慢。
  • 我認爲你不想要sequence。你可能會根據你想要做什麼,但我認爲你更可能在Data.Maybe尋找catMaybes。不過,我會建議你不要使用它,但自己實施它的學習效果。
0

jpath表示你可以尋找catMaybes函數,但是你最好自己實現學習。但是,如果有人來到這裏不是學習,只是爲了獲得完整的解決方案,然後在這裏它是:

import Data.Maybe (catMaybes) 

ex :: [[Maybe a]] -> [[a]] 
ex = map catMaybes