2016-02-17 55 views
0

以下是兩段代碼。Haskell頭部/尾部與花紋匹配

工作:

joins :: [String] -> String -> String 
joins [] _ = "" 
joins [x] _ = x 
joins xs d = head xs ++ d ++ (joins (tail xs) d) 

不工作:

joins :: [String] -> String -> String 
joins [] _ = "" 
joins [x] _ = x 
joins [x:xs] d = x ++ d ++ (joins xs d) 

的錯誤日誌,後者則是:

test.hs:4:18: 
Couldn't match expected type `[Char]' with actual type `Char' 
In the first argument of `(++)', namely `x' 
In the expression: x ++ d ++ (joins xs d) 
In an equation for `joins': 
    joins [x : xs] d = x ++ d ++ (joins xs d) 

test.hs:4:35: 
Couldn't match type `Char' with `[Char]' 
Expected type: [String] 
    Actual type: [Char] 
In the first argument of `joins', namely `xs' 
In the second argument of `(++)', namely `(joins xs d)' 
In the second argument of `(++)', namely `d ++ (joins xs d)' 

缺少什麼我在這裏?

+0

注意'Data.List'提供了'intercalate'功能這一點。 – dfeuer

+1

上面的代碼僅用於學習目的,但在真實項目中,我將使用您建議的功能。 – Eugene

回答

5

使用括號,括號不:

-- vvvvvv 
joins (x:xs) d = x ++ d ++ (joins xs d) 

與長度爲1的列表中,其單個元件是一個非空列表x:xs圖案僅[x:xs]匹配。

因爲你是一個字符串列表,[x:xs]["banana"]場比賽(其中x='b', xs="anana"),用["a"]x='a', xs=""),但與["banana", "split"]也不符合[""]

這顯然不是你想要的,所以使用簡單的圓括號。

(順便說一下,不需要在... ++ (joins xs d)括號:功能應用的優先級比在Haskell任何二進制運算符的更多。)

+0

這個伎倆! – Eugene

+0

如果它讓你感覺更好,這至少是本月我用'[x:xs]'而不是'(x:xs)'看到的第二個問題...... – MathematicalOrchid

+0

@MathematicalOrchid確實,這是一個常見的錯誤。我也見過'f [x] = ...',其中'x'被假定多次與輸入列表匹配。我總是想知道這些錯誤傳播的原因是什麼。 – chi