解释这个哈斯克尔功能"list of tuples to list"



我是初学者,基本上我需要对此进行解释

他用这个代码回答:

tupleToList :: [(a,a)] -> [a]
tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList _          = []

但我不明白他为什么不使用:

tupleToList [] = []
tupleToList ((a,b):xs) = a : b : tupleToList xs

就像我通常在指南的第一个练习中看到的那样。 我知道"_"是什么,但是,当列表为空时,使用"[]"不是更好吗?

就像我通常在指南的第一个练习中看到的那样。我知道_是什么,但是,当列表为空时,使用[]不是更好吗?

在语义上,两者是相同的,因为一个2元组只有一个构造函数(a,b),而一个列表有两个构造函数[](h:t)

由于唯一与第一个子句不匹配的模式是空列表,因此通配符_等效于[]

由于[]((a,b):xs)析取模式(即没有值可以匹配两种模式(,因此当显式使用[]时,两种模式的顺序并不重要。然后,我们可以按照我们喜欢的任何顺序编写它。

一些Haskell程序员更喜欢使用显式模式(所以使用[]而不是_(,因为这意味着我们知道我们实际使用该子句处理哪些值。如果以后Haskell社区决定引入一个额外的列表构造函数(是的,对于列表来说,这不太可能,但对于其他data类型,这可能更合理(,Haskell编译器可以(-Wincomplete-patterns(给出警告,指出某些模式没有被覆盖。通配符当然涵盖了所有模式,但也许右侧的表达式不是我们为附加构造函数准备的表达式。

因此,我建议仅在您想通过同一子句匹配多个模式时才使用通配符。如果清楚其他模式是什么,最好明确。就像Python的Zen所说(是的,它是Python,但大多数概念在某种程度上是通用的(:">显式比隐式更好"。

没有区别:它们的语义完全相同。

tupleToList [] = []
tupleToList ((a,b):xs) = a : b : tupleToList xs

相当于

tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList [] = []

相当于

tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList _ = []

通常,当我们需要模式匹配多个情况时,会使用通配符_。 例如

myAnd :: Bool -> Bool -> Bool
myAnd True  y = y
myAnd False _ = False

上面,我们可以分别枚举False FalseFalse True情况,并使用三个方程,但使用通配符更方便(并且使我们的函数稍微懒惰,例如myAnd False undefined计算结果为False(。

最后,这主要是风格问题。通常,当通配符_只能代表一种情况时,最好将其拼写出来,明确说明。这样,代码通常更具可读性。例如

not :: Bool -> Bool
not False = True
not _     = False

等效但比

not :: Bool -> Bool
not False = True
not True  = False

当然,case表达也是如此。

case x of
Just y  -> 1 + y
Nothing -> 0

可以说比

case x of
Just y -> 1 + y
_      -> 0

最新更新