2016-02-25 112 views
0

我似乎無法包裝我的頭如何通過Haskell列表列表進行遞歸。這是我的問題:Haskell - 通過列表列表遞歸?

type Symbol = String 
type Sentence = [[Symbol]] 

getSymbols :: [Sentence] -> [Symbol] 
getSymbols [[]] = [] 
getSymbols ((sym:stmt):(stmts)) 
    | stmt == [] = getSymbols stmts 
    | sym `elem` stmt = getSymbols ((stmt):(stmts)) 
    | otherwise = sym : getSymbols ((stmt):(stmts)) 

我想要返回給定句子中找到的所有符號列表中沒有重複出現,例如,

getSymbols [["A","B","C"],["D","A"],["E","B","C"]] 

將返回:

["A","B","C","D","E"] --order does not matter-- 

我一直在嘗試一些不同的方法,但似乎仍不能得到 - 我現在仍然在哈斯克爾相當原始,所以也許有一些明顯的我我錯過了。幫助將不勝感激,謝謝。

+0

你可能會嘗試將問題分解爲更容易的子問題?例如。首先創建一個包含所有內容的大列表,然後刪除重複項。那麼你的問題的答案就是編寫這些簡單的函數。 – gallais

+0

@gallais是否需要我編寫更多的函數,還是可以在單個函數中完成?因爲我只想用一個函數來解決問題 – willrobertshaw

+2

@willrobertshaw我不認爲這是個好主意。函數式編程的核心是組成函數。您越早習慣編寫小型可組合函數越好。想想什麼是更通用的小型樂高積木或玩具車? – epsilonhalbe

回答

1

試試這個:

import Data.List 
nub . concat $ [["A","B","C"],["D","A"],["E","B","C"]] 
+3

你會添加一些解釋,顯然OP是不感興趣的結果,但如何以及爲什麼 – epsilonhalbe

1

試試這個:

getSymbols   [] = [] 
getSymbols ( [] :xss) = getSymbols xss 
getSymbols ((x:xs):xss) 
    | x `elem` (getSymbols (xs:xss)) =  getSymbols (xs:xss) 
    | otherwise      = x : (getSymbols (xs:xss)) 
+0

嗨 - 我試過這個,但我在最後一行發生類型錯誤「無法匹配類型'[Char]'與'字符' 預期類型:標記 實際類型:[Symbol] 在'(:)'的第一個參數中,即'sym' 在表達式中:sym:(getSymbols(stmt:stmts))「任何幫助? – willrobertshaw

0

@gallais會需要我寫更多的功能或可它仍然是 在一個單一的功能呢?因爲我想只是一個單一的功能來解決這個問題

這是明智的要簡單的解決方案,但減少了使用功能的數量是不是你如何實現與哈斯克爾這一目標。相反,要找到想要重用定義的簡單解決方案。您希望將問題的解決方案看作是對較小問題的已知解決方案的組合。這讓你只需記住一點就可以解決很多事情。

於是,我們開始像這樣的列表:

[["A","B","C"],["D","A"],["E","B","C"]] 

,我們希望找到一個包含所有相同的字符串,沒有別人,沒有重複的列表。如果我們將列表與concat :: [[a]] -> [a]拼合起來怎麼辦?

["A","B","C","D","A","E","B","C"] 

鑑於同樣的問題陳述,很明顯我們會得出同樣的答案。所有重要的是弦是什麼;其餘的結構是不相關的。

從這裏我們只需要刪除列表中的重複項。有幾種方法可以做到這一點。效率低下的是nub :: Eq a => [a] -> [a]。更有效的方法是Set.toList . Set.fromList :: Ord a => [a] -> [a]import qualified Data.Set as Set。無論我們選擇,我們的解決方案是這樣的:

nub . concat 

獎勵:設計一種方法刪除的使用從Data.Listsort :: Ord a => [a] -> [a]重複。