例如以下功能:
fun fac (0 : int) : int = 1
| fac (n : int) : int = n * fac (n - 1)
或者在函数中:
fun even 0 = true
| even x = odd(x-1)
and odd 0 = false
| odd x = even(x-1);
我对ML的经验不多,我只是想了解基础知识。
答案 0 :(得分:7)
这是pattern matching。从链接:
功能可以由一个或多个规则组成。规则由其函数名,参数模式及其表达式组成。调用该函数时,参数值将以自上而下的顺序与模式匹配。使用模式匹配的函数与case表达式非常相似
这意味着管道将案例分开以进行模式匹配。模式匹配匹配特殊模式并基于该模式执行特定表达式。它们遵循以下语法:
fun <fun-name> <pattern>
| <fun-name> <pattern>
| <fun-name> <pattern>;
<pattern>
的位置:
<args> = <expressions>
在您的第一个示例中,它为声学计算声明函数fac
。第一个模式是参数int
为0时。如果int
为0,则执行该情况的表达式,在这种情况下,如果传递的参数为0,则结果为1(因为0阶乘是1)。如果传递的参数不是0 ,则它遵循下一个模式(因为它与第一个模式不匹配)。如果传递的参数是2,那么它将执行递归并相应地找到阶乘。
考虑下面的代码段:
fun past "run" = "ran"
| past "swim" = "swam"
| past x = x ^ "ed";
我们定义名为past
的函数,它接受一个参数并找到参数的传递时。第一种模式相当于 - 用简单的英语:
如果单词(或传递的参数)是“run”,则传递的时态是“run”。
第二种模式相当于:
如果单词(或传递的参数)是“游泳”,则传递的时态是“游泳”。
如果单词既不是“游泳”或“运行”(因此两个模式不匹配)继续使用最后一个模式,只是在单词的末尾加上“ed”。
通过该示例,您可以看到|
(管道)符号分隔模式。你可以想到像这种伪代码的模式:
if argument is "run", then passed tense is "ran"
else if argument is "swim", then passed tense is "swam"
else add "ed" to end of word
模式匹配用于覆盖不规则的情况。由于“跑”和“游”是不规则通过时态,我们用模式覆盖那些案例。完全相同的原则适用于第一个例子 - 0!是一个特例,它是1.因此,我们可以使用模式匹配来匹配参数为0的特定情况,并根据特定情况执行。
答案 1 :(得分:0)
您所看到的是同时在参数上定义函数和模式匹配的快捷语法。如果从函数定义中分离出模式匹配,它将如下所示:
fun fac (x : int) : int =
case x of
0 => 1
| n => n * fac (n - 1)