Functional programming 具有连续性问题的F#扩展欧几里得算法
我是F#的新手,从本科开始就没有做过函数式编程,但我一直在尝试自学。我编写了一个朴素的递归扩展欧几里德实现,它工作得很好,现在正在继续尝试 我用一个小例子手工浏览了两次代码,得到了正确的答案,但是当我通过解释器运行代码时,我没有得到相同的结果,所以我显然误解了我正在尝试做的事情 我手动运行eea 7 3,我计算的(正确)结果是(1,1,-2) 但是当我在解释器中运行它时Functional programming 具有连续性问题的F#扩展欧几里得算法,functional-programming,f#,continuations,Functional Programming,F#,Continuations,我是F#的新手,从本科开始就没有做过函数式编程,但我一直在尝试自学。我编写了一个朴素的递归扩展欧几里德实现,它工作得很好,现在正在继续尝试 我用一个小例子手工浏览了两次代码,得到了正确的答案,但是当我通过解释器运行代码时,我没有得到相同的结果,所以我显然误解了我正在尝试做的事情 我手动运行eea 7 3,我计算的(正确)结果是(1,1,-2) 但是当我在解释器中运行它时 eea 7 3;; val it : int * int * int = (1, 0, 1) 以下是我的实现: let ee
eea 7 3;;
val it : int * int * int = (1, 0, 1)
以下是我的实现:
let eea a b =
let rec contEEA a b f =
match b with
| 0 -> f () (a,1,0)
| _ ->
contEEA b (a%b) (fun () t ->
let (d,x',y') = t
(d, y', x'-(y'*(a/b)))
)
contEEA a b (fun () t -> t)
作为参考,直接来自教科书的幼稚方法是
let rec eea_gcd a b =
match b with
| 0 -> (a, 1, 0)
| _ ->
let d, x', y' = eea_gcd b (a % b)
(d, y', x'-(y'*(a/b)))
基于延续的版本总是只执行一次迭代(最后一次)。在进行递归调用时,continuation直接返回结果,而不是通过传递到上一个continuation将结果“返回”到上一个调用 因此,调用顺序如下所示:
eea 7 3
conteea73(fun()t->t)
b 0
==>第二种情况匹配conteea31(fun()t->…(d,y',…)
b 0
==>第二种情况匹配conteea10(fun()t->…(d,y',…)
b=0
=>第一个案例匹配f()(1,1,0)
(1,0,1-(0*(3/1))=(1,0,1)
,并立即返回它(1,0,1)
的结果时,它应该将其传递给上一个continuation,以便它可以从那里继续计算,最终将结果传递给第一个continuationfun()t->t
,后者将其返回给使用者
为此,请更换该行:
(d, y', x'-(y'*(a/b)))
为此:
f (d, y', x'-(y'*(a/b)))
另外,还有一些其他方面的注意事项。
()
)不是必需的,因为它从未实际使用过(怎么可能?),您可能会丢失它funt->t
,它有一个特殊的名称id
(也称为“标识函数”)let
来分解三元组。参数可以是模式let eea a b =
let rec contEEA a b f =
match b with
| 0 -> f (a,1,0)
| _ ->
contEEA b (a%b) (fun (d,x',y') ->
f (d, y', x'-(y'*(a/b)))
)
contEEA a b id