我確實有以下代碼:
data List = Empty | Cons Integer List deriving Show
list = Cons 1 (Cons 7 (Cons 9 (Cons 3 Empty)))
現在我正在撰寫一個函式,該函式將串列中的每個第二個元素加倍:
double2nd :: List -> List
double2nd Empty = Empty --If the list is empty, nothing to do
double2nd (Cons x y z) = ???
我有以下測驗用例:
testDouble = putStrLn ("expected: Cons 1 (Cons 14 (Cons 9 (Cons 6 Empty)))\ncomputed: " show (double2nd list))
我嘗試在各種網頁上查找串列,但沒有得出結論。
任何幫助或任何我可以學習的頁面將不勝感激。
uj5u.com熱心網友回復:
Stuf 在其他語言中通常用回圈完成,在 haskell 中用遞回完成:
double2nd :: List -> List
double2nd Empty = Empty -- check if list is completexly empty
double2nd (Cons i Empty) = Cons i Empty -- check if list is only containing one element
double2nd (Cons i (Cons i2 l))= Cons i (Cons (i2 * 2) (double2nd l)) -- recusion step
uj5u.com熱心網友回復:
Cons 需要兩個引數,一個 Integer 和一個 List,因此你不能模式匹配Cons x y z。
double2nd :: List -> List
double2nd Empty = Empty --If the list is empty, nothing to do
double2nd (Cons x (Cons y (Cons z Empty))) = ... -- this will match a 3 element list
請注意,Cons 的第二個引數是一個串列。但是這種模式不太正確,它只適用于正好有 3 個元素的串列。這發生在我們嘗試再次匹配串列時:
λ> Cons x (Cons y (Cons z Empty)) = list
λ> [x,y,z]
[*** Exception: <interactive>:151:1-39: Non-exhaustive patterns in Cons x (Cons y (Cons z Empty))
-- making it work with exactly 3 elements:
λ> Cons x (Cons y (Cons z Empty)) = Cons 1 (Cons 7 (Cons 9 Empty))
λ> [x,y,z]
[1,7,9]
-- making it work with larger lists:
λ> Cons x (Cons y (Cons z _)) = Cons 1 (Cons 7 (Cons 9 Empty))
λ> [x,y,z]
[1,7,9]
最后一個模式_忽略了最后一個 Cons 的第二個引數的值,它有丟失這個值的缺點。我懷疑要解決您的問題,您需要在所有元素上運行該函式。為此,我們可以使用@以下方法系結到匹配的模式:
λ> Cons x (Cons y (Cons z tl@_)) = list
λ> [x,y,z]
[1,7,9]
λ> tl
Cons 3 Empty
修復您的功能:
double2nd :: List -> List
double2nd Empty = Empty
double2nd (Cons x (Cons y (Cons z tl@_))) = Cons x (Cons (2*y) (Cons z tl))
-- ^ will match list with 3 or more elements
λ> double2nd list
Cons 1 (Cons 14 (Cons 9 (Cons 3 Empty)))
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/330330.html
