myPen :: [a] -> a
myPen [] = error "空的串列沒有倒數第二個元素。"。
myPen list@(_:xs)
| length list == 1 = error "大小為1的串列沒有倒數第二個元素。"2 = head xs
|否則 = myPen xs
這段代碼可以編譯,但是當給定輸入時,
myPen [1, 2]
它產生了錯誤
*** Exception: Lists size 1 沒有倒數第二個元素。
CallStack(來自HasCallStack)。
錯誤,在prob1_10.hs:16:25 in main:Main呼叫。
據我所知,在這種情況下,@應該允許參考整個串列,然而它似乎只參考了串列的xs或尾部部分。
這似乎支持它應該包括x和xs的論點。
我的問題有兩個:
1.
1.) 為什么會這樣? 2.) 指向整個串列的正確方法是什么?
uj5u.com熱心網友回復:
在這種情況下發生的事情實際上是:length list == 2,但是length xs == 1,所以第一個或第二個防護都不會匹配。otherwise防護將被占用,并在xs上遞回呼叫該函式,該函式的長度為1,所以第一個防護將被占用,錯誤資訊將被列印。你可以通過寫:
myPen :: [a] -> a
myPen [] = error "空的串列沒有倒數第二個元素。"。
myPen list@(_:xs)
| length list == 1 = error "大小為1的串列沒有倒數第二個元素。"2 = head list
|否則 = myPen xs
但是在Haskell中,通常用模式匹配而不是用length函式來做這件事更常見,比如:
myPen :: [a] -> a
myPen [] = error "空的串列沒有倒數第二個元素。"。
myPen [_] = error "大小為1的串列沒有倒數第二個元素。"。
myPen [x,_] = x
myPen (_:xs) = myPen xs
uj5u.com熱心網友回復:
Haskell在概念上是自上而下地評估的。這意味著它首先看串列是否是空的。然后它查看 list 的長度,它是兩個,所以這個衛兵不會發生。然后它查看 length xs 是否為 2,但這也不是事實,因為 xs 是串列的尾部,所以 [2] 的長度為 1。
最終,它用myPen [2]進行了一個遞回呼叫,然后第一個衛兵(length list)確實是一個,因此它引發了一個錯誤。
因此,你可能想用以下方法來檢查整個串列:
myPen :: [a] -> a
myPen [] = error "空的串列沒有倒數第二個元素。"。
myPen list@(_:xs)
| length list == 1 = error "大小為1的串列沒有倒數第二個元素。"2 = head list -- 檢查 list 的長度。
|否則=myPen xs
然而,使用length是不可取的,因為它需要線性時間來確定長度,而且對于長度無限的串列,它會陷入無限的回圈。你最好用模式匹配來作業,所以:
myPen :: [a] -> a
myPen [] = error "空的串列沒有倒數第二個元素。"。
myPen [_] = error "大小為1的串列沒有倒數第二個元素。"。
myPen [_,x] = x
myPen (x:xs) = pen xs
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/316974.html
標籤:
上一篇:無法打開dat.txt檔案
