为什么_匹配0?

时间:2014-09-14 11:09:06

标签: haskell pattern-matching

嘿,我见过以下函数声明

half :: Int -> Int
half (x+2) = 1 + (half x)
half _ = 0

为什么最后一行与零匹配,为什么该函数有效?

2 个答案:

答案 0 :(得分:9)

要回答标题问题:_匹配任何内容

  

前奏>案例0的_ - > "匹配"
  "匹配"
  前奏> case _的真实 - > "匹配"
  "匹配"
  前奏>案例" Eeeek" of _ - > "匹配"
  "匹配"
  前奏> case undefined of _ - > "匹配"
  "匹配"

但这似乎并不是你的问题;在您的示例_匹配 0,但映射到 0。所以答案是"为什么"基本上是#34;因为它是以这种方式定义的#34;。至于为什么这会产生一个有用的功能:_模式再次匹配任何东西 - 任何都不匹配以前的模式之一。现在,在您的情况下,之前的模式恰好是一个讨厌的n+k-pattern, which isn't actually legal in modern Haskell。我认为标准的替代方案确实更具有解释性:

half x | x>=2  = 1 + half (x - 2)
half _ = 0

所以,如果我们假装签名是

half :: Nat -> Nat

然后第二个条款基本上只是

half 1 = 0
half 0 = 0

对整数除法有明显的意义。

第一个子句可行的原因可能并不那么明显。但是你可以通过将x描绘成一个"资源"来轻松掌握它。这是以递归方式消耗的:你不断从中取走两个单位,每次都在结果中加一个单位。最后,结果将是x'的一半。原始价值。

答案 1 :(得分:1)

它匹配,因为要匹配的模式只是一个"变量",所以它将匹配任何值。

说你有这个功能:

fun :: Int -> String
fun 1 = "one"
fun 2 = "two"
fun x = "other"

由于最后一个模式是变量,因此它将匹配 12的任何数字。但请注意,我们实际上并没有在最后一个模式中使用 x;我们只是用它来匹配任何数字。如果我们不想为我们甚至不会使用的变量提出名称,该怎么办?答案就是下划线(_)。我们只需将上一场比赛中的x替换为_

即可
fun _ = "other"