2016-02-17 102 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