的問題是在你的代碼的最後一行:
(x : xs) -> x ++ sep ++ strJoin sep xs
模式x : xs
的含義是x
將匹配一個元素,即列表的第一個元素,xs
將匹配列表,即除第一個元素外的所有元素的列表。該列表可以是空的。具體而言,如果arr
包含單個元素,則x
將與該單個元素匹配,並且xs
將與列表的其餘部分匹配,該列表是空列表。但隨後,在右手邊的,這樣就:
x ++ sep ++ strJoin sep []
這相當於
x ++ sep ++ ""
這又是一樣的
x ++ sep
這解釋的行爲你的功能。那麼我們如何解決這個問題呢?一種解決方案是嘗試更改該案例的模式,以便該規則不會在具有單個元素的列表上使用。要做到這一點的方法之一是,像這樣:
(x : xs @ (_ : _)) -> x ++ sep ++ strJoin sep xs
這裏xs @ (_ : _)
將匹配一個非空列表。我將把這個解釋作爲一個練習。 因此,現在該規則不會用於單個元素列表,因爲我們想要,但問題是沒有這樣的列表的規則了。所以我們需要添加一個新的。下面將做:
[x] -> x
所以把他們放在一起:
strJoin sep arr = case arr of
[] -> ""
(x : xs @ (_ : _)) -> x ++ sep ++ strJoin sep xs
[x] -> x
當然還有很多其他的方法可以做到這一點,這裏有一個:
strJoin sep arr = case arr of
[] -> ""
[x] -> x
(x : xs) -> x ++ sep ++ strJoin sep xs
我會離開它作爲一個練習如何運作。
感謝您回答這個問題。我第一次看到@,我會找到解釋它是如何工作的。順便說一句你的第二個解決方案更具可讀 – Raj