(:)在Haskell中做了什么?

时间:2014-04-01 11:26:22

标签: haskell

我试过在hoogle和其他各种haskell词典中查找它,但我无法找到它。我的印象是它的前提,但我开始以前所未有的方式看到它并且我开始第二次猜测自己。

例如,这是我不理解的问题之一:

(3分)用一个模式填充空白,以便fun1 [(5,6),(7,8)]返回 5和fun1 [(10,20),(30,40),(50,60)]返回10:

答案显然是:

         ((y,_):_)
  fun1 _____________ = y

但我对此感到困惑。我知道下划线意味着你并不真正关心那些类型是什么,但我不明白(:)在这个答案中的作用。

5 个答案:

答案 0 :(得分:7)

虽然其他答案正确解释了:他们没有完全回答这个问题的答案 - 在您的问题答案中:并未用作函数,但作为模式匹配的构造函数。 fun (x:xs) = x表示"如果参数是格式(x:xs),则给我x"。模式匹配用于"拉开"基于Haskell中构造函数的复杂类型。

特别是,由于:是一个列表构造函数,您可以使用:拉开列表

(从概念上讲,列表定义为data [] a = [] | (:) a [a],虽然你不会因为它的内置语法而编译它。

非列表示例:我们可以定义数据类型data F a b = A a | B b。这将创建一个F类型,其中包含两种类型ab以及两种构造函数AB,其类型为{{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 asa: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]这样的列表,则会将x5匹配,将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)]匹配。现在y5,这是我们返回的值。同样,由于我们不使用zxs,我们可以将函数编写为:

fun1 ((y,_):_) = y