Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell-一个非常简单的函数_List_Haskell - Fatal编程技术网

List Haskell-一个非常简单的函数

List Haskell-一个非常简单的函数,list,haskell,List,Haskell,我试图理解以下函数: 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中的列表至少在概念上是一个链表。有两种可能性: 空

我试图理解以下函数:

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:[])

为什么这很重要?我们首先尝试理解
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::xs)
,它是
(x:(:xs))
的缩写。下划线的基本意思是“不在乎”。所以列表应该是一个cons,其中尾部也是cons,我们感兴趣的是列表的头部
x
,以及列表的尾部
xs

如果我们对此进行推理,我们就会发现
q1
返回奇数索引处元素的最大值(因此第一个、第三个、第五个等元素)。如果列表长度为偶数,我们也会用零计算最大值(因此,如果奇数索引处的所有元素都为负数,则函数将返回零,但这仅限于偶数长度列表的情况)

现在如果我们用
q1(map abs[-1,-6,-5,7])
来调用它,这意味着我们将在
[-1,-6,-5,7]
上调用
map abs
的结果
map abs
构造一个列表,其中
abs
应用于列表的所有元素(尽管它是惰性应用的)。所以在
映射abs[-1,-6,-5,7]
之后,我们获得列表
[1,6,5,7]
。现在奇数索引处的元素是
1
5
。因此
q1
将计算这些元素的最大值和零(因为列表的长度是4,这是偶数)。最大值(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)

模式
x:xs:xs
与至少包含两个元素的列表相匹配;第一个元素命名为
x
,第二个元素被丢弃,列表的其余部分(除前两个元素外)命名为
xs
。这是否阐明了这种模式的含义?是的,这就解释了。现在觉得自己很愚蠢,因为我错过了第二个被丢弃的机会。。。谢谢该死,这是一个非常好的回答,一个彻底的回答!我不知道在问之前我们会通过奇怪的指数,但现在我完全明白为什么我会得到5!非常感谢您花时间回答这个问题!。。。然后你说
q3。地图abs
超过了列表,因此相当于
最大值。(0:) . 地图(abs.head)。chunksOf 2
或什么的。@WillNess:当然可以,但最后一节更像是对
q
根本不是一个好函数这一事实的评论,不是为了设计更好的函数,只是用外行的话简单概述了两个选项:)顺便说一句
0
东西意味着
q1
期望(不需要)它在列表中的参数都是非负的,这是它接口的一个重要部分(不是由它的类型捕获的)。与
映射abs
也很相配。@WillNess:没错,而且它不受类型限制,也不执行
abs
本身,也不总是使用零,这使得它的功能非常糟糕。