我试过在hoogle和其他各种haskell词典中查找它,但我无法找到它。我的印象是它的前提,但我开始以前所未有的方式看到它并且我开始第二次猜测自己。
例如,这是我不理解的问题之一:
(3分)用一个模式填充空白,以便fun1 [(5,6),(7,8)]返回 5和fun1 [(10,20),(30,40),(50,60)]返回10:
答案显然是:
((y,_):_)
fun1 _____________ = y
但我对此感到困惑。我知道下划线意味着你并不真正关心那些类型是什么,但我不明白(:)在这个答案中的作用。
答案 0 :(得分:7)
虽然其他答案正确解释了:
他们没有完全回答这个问题的答案 - 在您的问题答案中:
并未用作函数,但作为模式匹配的构造函数。 fun (x:xs) = x
表示"如果参数是格式(x:xs),则给我x"。模式匹配用于"拉开"基于Haskell中构造函数的复杂类型。
特别是,由于:
是一个列表构造函数,您可以使用:
拉开列表
(从概念上讲,列表定义为data [] a = [] | (:) a [a]
,虽然你不会因为它的内置语法而编译它。
非列表示例:我们可以定义数据类型data F a b = A a | B b
。这将创建一个F
类型,其中包含两种类型a
和b
以及两种构造函数A
和B
,其类型为{{1}分别和a -> F a b
。
然后,您可以编写使用模式匹配的函数来获取包含的值,例如
b -> F a b
或
isA (A _) = True -- this value was constructed with A, so it is an A
isA (B _) = False -- this value was constructed with B so it is not an A
答案 1 :(得分:4)
它是一个List构造函数。它用于在列表前面添加任何值。
ghci> 2 : [3,4]
[2,3,4]
这只是另一个Haskell功能。您还可以在ghci中看到它的类型:
ghci> :t (:)
(:) :: a -> [a] -> [a]
关于你的问题,答案就像这个((y,_):_)
,因为它被用于模式匹配。第一个_
是该对的第二个元素,第二个_
模式与列表匹配。
这可能会对您有所帮助:
ghci> (5,6):[(7,8)]
[(5,6),(7,8)]
答案 2 :(得分:3)
:
是a -> [a] -> [a]
类型的列表构造函数。它通常用于中缀。但如果用括号括起来,你可以用它作为前缀。就像任何中缀操作一样。 (例如(+) 4 5 == 4 + 5
)
因此(:) a as
与a:as
如果模式中的构造匹配,也可以使用Haskell中的每个构造函数来解构类型的值:
f x:xs = xs
例如,将定义一个采用非空列表并返回尾部的函数。它会在空列表上失败,因为空列表由空构造函数[]
构造。您可以通过将第二个构造函数添加到匹配项中来使f
总计。
f [] = []
我想你的困惑来自这样一个事实:在haskell中有一个语法糖,它允许你以更方便的方式编写列表。您可以编写(1:(2:(3:[])))
而不是[1,2,3]
,而编译器会将其扩展为前者。
答案 3 :(得分:2)
除了(:)
函数的答案之外,请记住,在您的问题的上下文中:
被用作解构函数。
最好将(:)
视为构造函数。然后,就像任何其他数据构造函数一样,它可以用于内省值的内容。例如:
f (Just x) = x -- extracts the value wrapped into Maybe a
f (x:_) = x -- extracts the value wrapped into a list, [a]
f ((x,_):_) = x -- extracts the value wrapped into a tuple in the list of tuples
在所有这些情况下,Just
,:
和(,)
都是构造函数。可以使用相同的语法来构造或解构值 - 取决于表达式的上下文。比较:
f x = Just x -- wraps x into Maybe a
f x xs = x:xs -- wraps x into a list, [a]
f x y z = (x,y):z -- wraps x into a tuple in the list of tuples
答案 4 :(得分:1)
要了解fun1
的作用,请先查看另一个功能:
f (x:xs) = x
如果您将此功能传递给[5,12,33]
这样的列表,则会将x
与5
匹配,将xs
与[12,33]匹配。该函数只返回x
,即第一个元素。所以这个函数与head
基本相同。由于我们实际上并未使用值xs
,因此我们可以将函数重写为:
f (x:_) = x
现在让我们看fun1
,但稍微修改一下。
fun1 ((y,z):xs) = y
如果我们将此功能传递给[(5,6),(7,8)]
列表,它会将(y,z)
与(5,6)
对和xs
与[(7,8)]
匹配。现在y
是5
,这是我们返回的值。同样,由于我们不使用z
或xs
,我们可以将函数编写为:
fun1 ((y,_):_) = y