繁体   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