functional-programming - 模式匹配中的变量如何允许参数省略?

标签 functional-programming pattern-matching ocaml exponentiation

我正在做一些家庭作业,但我在某件事上被困了几个小时。 我确信这真的很微不足道,但在仔细阅读了所有可用的文档后,我仍然无法理解它。 有人可以帮我吗? 基本上,OCaml 编程中的练习要求用平方算法求幂来定义函数 x^n。

我看过解决方案:

   let rec exp x = function
    0 -> 1
   | n when n mod 2 = 0  -> let y = exp x (n/2) in y*y
   | n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
   ;;

我特别不明白的是参数 n 如何从 fun 语句中省略以及为什么它应该用作与 x 匹配的变量,这与平方求幂的定义没有明显联系.

这是我的做法:

   let rec exp x n = match n with
   0 -> 1
   | n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
   | n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
   ;;

最佳答案

您的版本在语法上是正确的,产生了一个很好的答案,但执行时间很长。 在您的代码中,exp 被递归调用两次,因此产生两倍的计算量,每次调用产生两倍的计算量,等等直到 n=0。方案中,exp只调用一次,结果保存在变量y中,然后对y求平方。

现在,关于语法,

let f n = match n with
  | 0 -> 0
  | foo -> foo-1

相当于:

let f = function
  | 0 -> 0
  | foo -> foo-1

let rec exp x = function 是一个函数的开头,该函数接受两个 参数:x,并使用了一个未命名的参数在模式匹配中。在模式匹配中,行

 | n when n mod 2 = 0  ->

将此参数命名为 n。并不是说在模式匹配的每种情况下都可以使用不同的名称(即使那样不太清楚):

| n when n mod 2 = 0  -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x

关于functional-programming - 模式匹配中的变量如何允许参数省略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12996668/

相关文章:

ios - 使用函数式编程将嵌套的字符串数组转换为嵌套的 double 组

c# - 合并空检查和模式匹配的 'if'语句时出错

stream - 如何使用 Stream.iter 在 OCaml 中处理来自标准输入的行

Ocaml 模式与数据构造函数的匹配与其数量无关

ocaml - 是否可以在函数内部定义异常

python - 如何在列表字典中获取特定值

haskell - 关于函数式编程

java - 如何跳过java流中的连续元素?

java - 字符类中的元字符 (`[]` )

rust - 针对元组的模式匹配