嘿,我见过以下函数声明
half :: Int -> Int
half (x+2) = 1 + (half x)
half _ = 0
为什么最后一行与零匹配,为什么该函数有效?
答案 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"
由于最后一个模式是变量,因此它将匹配不 1
或2
的任何数字。但请注意,我们实际上并没有在最后一个模式中使用 x
;我们只是用它来匹配任何数字。如果我们不想为我们甚至不会使用的变量提出名称,该怎么办?答案就是下划线(_
)。我们只需将上一场比赛中的x
替换为_
:
fun _ = "other"