簡體   English   中英

Haskell - 一個非常簡單的功能

[英]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中的列表 - 至少在概念上 - 是一個鏈表 有兩種可能性:

  • 空列表[] ; 要么
  • 一個“cons” (x:xs) ,其中x頭部 (第一項), xs尾部 (列表的其余部分)。

Haskell也使用了語法糖 例如[1]在幕后翻譯成(1:[])[1,4,2,5](1:(4:(2:(5:[]))))

為什么這很重要? 我們首先會嘗試了解q1函數。 如果我們查看類型,我們會看到q1Int s列表作為輸入,並返回Int 它以遞歸方式定義為:

q1 :: [Int]  -> Int
q1 [] = 0
q1 [x] = x
q1 (x:_:xs) = max x (q1 xs)

這意味着空列表的q1為零( 0 ); 具有一個元素x的列表的q1x 對於具有兩個或更多元素的列表,該列表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] 現在奇數索引處的元素是15 所以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM