[英]Haskell - a very simple function
我正在嘗試理解以下功能:
q1 :: [Int] -> Int
q1 [] = 0
q1 [x] = x
q1 (x:_:xs) = max x (q1 xs)
當輸入這個:q1(地圖abs [-1,-6,-5,7])時,它得到了我5.有人可以告訴我為什么會這樣嗎? 我理解map函數如何,但模式匹配(x:_xs)有點令人困惑。 謝謝!
Haskell中的列表 - 至少在概念上 - 是一個鏈表 。 有兩種可能性:
[]
; 要么 (x:xs)
,其中x
是頭部 (第一項), xs
是尾部 (列表的其余部分)。 Haskell也使用了語法糖 。 例如[1]
在幕后翻譯成(1:[])
, [1,4,2,5]
到(1:(4:(2:(5:[]))))
。
為什么這很重要? 我們首先會嘗試了解q1
函數。 如果我們查看類型,我們會看到q1
將Int
s列表作為輸入,並返回Int
。 它以遞歸方式定義為:
q1 :: [Int] -> Int
q1 [] = 0
q1 [x] = x
q1 (x:_:xs) = max x (q1 xs)
這意味着空列表的q1
為零( 0
); 具有一個元素x
的列表的q1
是x
。 對於具有兩個或更多元素的列表,該列表x
的第一項的maximum
和該列表尾部的尾部 。 這是因為我們模式匹配(x:_:xs)
,它是(x:(_:xs))
縮寫。 下划線基本上意味着“ 不在乎 ”。 因此,名單應該是一個缺點 ,其中尾部是一個缺點 ,以及,我們感興趣的是列表的頭部x
和表尾的尾xs
。
如果我們對此進行推理,我們就會發現q1
返回奇數索引處元素的最大值 (所以第一個,第三個,第五個等元素)。 如果列表具有偶數長度,我們還計算最大值為零(因此,如果奇數索引處的所有元素都是負數,則函數將返回零,但這僅在我們具有偶數長度列表的情況下)。
現在,如果WEL與稱之為q1 (map abs [-1,-6,-5,7])
它因而意味着我們將稱之為q1
上的結果 map abs
上[-1, -6, -5, 7]
。 map abs
構造一個列表,其中abs
應用於列表的所有元素(盡管它是懶惰地應用)。 所以在map abs [-1, -6, -5, 7]
,我們得到了列表[1, 6, 5, 7]
。 現在奇數索引處的元素是1
和5
。 所以q1
將計算這些元素的最大值和零(因為列表的長度是4,這是偶數)。 並且max(0,1,5)是5 。
就個人而言,尤其是我們也認為零,但僅在列表具有均勻長度的情況下,這是非常“ 不穩定 ”的事實。 它可能導致難以理解的錯誤,因為它可能是函數細節的結果。 我們可以例如用零計算最大值,而不管列表的長度如何:
q2 :: (Num a, Ord a) => [a] -> a
q2 [] = 0
q2 [x] = max 0 x
q2 (x:_:xs) = max x (q2 xs)
或者我們可以決定不使用零,而不是在空列表上定義最大值,例如:
q3 :: Ord a => [a] -> a
q3 [x] = x
q3 [x,_] = x
q3 (x:_:xs) = max x (q3 xs)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.