为什么在haskell中重复了函数名? (新手)

时间:2014-04-08 13:19:34

标签: haskell

为什么函数名称在

中重复

示例:

lucky :: (Integral a) => a -> String  
lucky 7 = "LUCKY NUMBER SEVEN!"  
lucky x = "Sorry, you're out of luck, pal!"   

什么时候不应该重复功能名称?这是什么意思?

感谢

4 个答案:

答案 0 :(得分:3)

您所看到的是模式匹配。

我会告诉你另一个例子:

test 1 = "one"
test 2 = "two"
test 3 = "three"

ghci中的演示:

ghci> test 1
"one"
ghci> test 2
"two"
ghci> test 3
"three"
ghci> test 4
"*** Exception: Non-exhaustive patterns in function test

因此,当您调用任何函数时,运行时系统将尝试匹配 具有已定义函数的输入。所以打电话给test 3会 最初检查test 1,由于1不等于3,它会 继续下一个定义。由于2不等于3, 它将进入下一个定义。在3以来的下一个定义中 等于3它将返回"three"字符串。当你尝试 模式匹配程序中根本不存在的东西 抛出异常。

答案 1 :(得分:3)

这种模式匹配可以转换为case语句(事实上,这就是编译器通常会做的事情!):

lucky' n = case n of
    7 -> "LUCKY NUMBER SEVEN!"
    x -> "Sorry, you're out of luck, pal!"

由于x并未真正使用,您通常会改为_ -> "Sorry, ..."

请注意, 2

相同
lucky'' n = if n==7 then ...

(==)的平等比较通常比模式匹配更昂贵 1 ,并且也更加丑陋。

<小时/> 1 为什么它更贵:假设我们有一个大数据结构。为了确定它们是相同的,程序将需要挖掘两个整个结构,确保所有分支都是相同的。但是,如果你模式匹配,你只需比较你现在感兴趣的一小部分。

2 实际上,在这种情况下是相同的,但仅仅因为编译器在数字上有一个特殊的模式匹配技巧:它用{{1重写它}}。这对于(==)类型来说非常特殊,对于其他任何类型都不是。 (除非您使用the OverloadedStrings extension。)

答案 2 :(得分:2)

我假设你在看learn you a haskell。在那个例子之后,它说

  

当你打电话给幸运时,将从上到下检查图案,当它符合图案时,将使用相应的功能体。

因此第一行表示函数的类型,后面的行是要检查的模式。每一行都有函数名,所以编译器知道你还在谈论相同的函数。

以这种方式思考:当您编写表达式lucky (a+b)或其他任何内容时,编译器将尝试将lucky (a+b)替换为函数定义中=之前的第一个内容“适合。”因此,如果a=3b=4,您将获得以下一系列替换:

lucky (a+b) =
lucky (3+4) =
--pattern matching occurs...
lucky 7 =
"LUCKY NUMBER SEVEN!"

这是使Haskell在实践中如此容易推理的部分原因;你得到一个与数学类似的系统。

答案 3 :(得分:2)

lucky的定义使用&#34;模式匹配&#34;和等于(在这种情况下)

lucky :: (Integral a) => a -> String  
lucky a = if a == 7
    then "LUCKY NUMBER SEVEN!"
    else "Sorry, you're out of luck, pal!"