试图让我的头脑(x:xs)和列表?

mac*_*ian 2 syntax recursion haskell list

我一直受到列表工作方式的挑战,并对整个(x:xs)概念感到困惑.我似乎并没有理解它.

select :: Ord a => a -> [a] -> [a]
select y [] = []
select y (x:xs)
    | x < y     = x : select y xs
    | otherwise = select y xs
Run Code Online (Sandbox Code Playgroud)

PS我确切地知道这个功能是做什么的,但是任何人都能够解释这个过程(包括特别怪异Ord a=>标志)吗?

任何有效的策略将不胜感激.

提前致谢.伊恩.

Don*_*art 9

好.让我们来看看这里不同的句法元素.

第1行

select :: Ord a => a -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

这是一种类型声明.它是函数的声明(因为它有->类型).

该函数有两个参数.

  • 第一个是任何类型的单个值,表示为a(小写表示它是多态类型).
  • 第二个参数是与第一个参数相同的任何类型的列表.

返回值是任何类型的列表,与参数类型相同.

Ord a组件是一个类型类约束,它表示给出此函数的任何类型也必须是Ord该类的实例.这是一类可以比较的类型.

第2行

现在我们来看第2行:

select y [] = []
Run Code Online (Sandbox Code Playgroud)

这是select函数本身的一个定义.它非常简单,包含两个参数的模式,以及结果的规范.它写道:

如果第一个参数是任何值(我们将命名y),第二个参数是空列表(由[]模式表示),则select计算为空列表.

第3行

第3行包含列表的另一种情况:

select y (x:xs)
Run Code Online (Sandbox Code Playgroud)

同样,这是select函数定义的一部分,对于第二个参数不是空列表的情况.如果它不是一个空列表,那么它是一个带有头部x和尾部的列表xs."cons"构造函数,(:)结合了列表头和尾.它也是我们如何在列表上进行模式匹配,以提取头部和尾部.

通过列表的头部和尾部的模式匹配(x:xs),我们将一个新变量绑定x到列表头部的xs值,并绑定到列表尾部的值.

第4和第5行

如果第二个参数是非空列表,则最后两行是基于附加检查测试和分支的附加保护:

| x < y     = x : select y xs
| otherwise = select y xs
Run Code Online (Sandbox Code Playgroud)

当第一个守卫x小于第一个参数时,它会发射y.如果是这样,我们将返回一个新的列表x,并select再次应用于尾部.

如果不是这种情况,那么我们x从列表中删除,并仅返回递归调用tail时发生的情况.


有关Haskell如何工作的更多信息,我建议介绍性文本,例如:

值得你的时间.