1
我是一名Haskell初學者,在真實世界Haskell的第2章中練習,在這裏你寫一個返回列表的倒數第二個元素的函數。爲什麼這個Haskell函數推斷爲這種類型?
我已經寫了下面的函數來試圖解決這個問題:
-- file: \Learn Haskell\lastButOne.hs
lastButOne xs = if length xs == 2
then head xs
else lastButOne tail xs
我不明白這是錯誤的編譯器會拋出:
lastButOne.hs:2:1: error:
• Couldn't match type ‘[a] -> [a]’ with ‘[t]’
Expected type: ([a] -> [a]) -> [t] -> t
Actual type: [t] -> t
• Relevant bindings include
lastButOne :: ([a] -> [a]) -> [t] -> t (bound at lastButOne.hs:2:1)
據我瞭解,ghci的認爲我的功能應該與它的類型不同,但我不明白爲什麼會發生這種情況,或者我該如何解決它。
編輯:謝謝你的答案!我已經更新了我的代碼:
-- file: \Learn Haskell\lastButOne.hs
lastButOne xs = if length xs == 2
then head xs
else if length xs < 2
then error "This list does not have a second-to-last element."
else lastButOne (tail xs)
這消除其中tail xs
被解釋爲兩個參數,而不是單一的表達錯誤。我還添加了一些確保列表不會太短的代碼。 Willem Van Onsem的解決方案更好,但作爲一項練習,我想我會想出一個解決方案,只使用本書中介紹的概念。
'lastButOne尾xs'是'(lastButOne尾)xs',不'lastButOne(尾XS)' – amalloy
你應該避免'head','儘可能多的尾巴「。他們不是慣用的Haskell,因爲1)如果你在空列表上使用它們,他們可能會崩潰你的程序,2)模式匹配更容易使用,也更方便。 – chi