首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在CPS中编写?

如何在CPS中编写?
EN

Stack Overflow用户
提问于 2011-12-17 01:29:29
回答 3查看 337关注 0票数 2

我正在尝试掌握延续传球风格(CPS),因此我正在重新编写加里不久前展示给我的一个例子。我没有他的示例源代码,所以我正在尝试根据记忆重新编写他的示例。考虑以下代码:

代码语言:javascript
复制
let checkedDiv m n =
    match n with
    | 0.0 -> None
    | _ -> Some(m/n)

let reciprocal r = checkedDiv 1.0 r

let resistance c1 c2 c3 =
     (fun c1 -> if (reciprocal c1).IsSome then 
        (fun c2 -> if (reciprocal c2).IsSome then
            (fun c3 -> if (reciprocal c3).IsSome then 
                Some((reciprocal c1).Value + (reciprocal c2).Value + (reciprocal c3).Value))));;

我不太明白的是如何构造阻力函数。我之前想出了这个:

代码语言:javascript
复制
let resistance r1 r2 r3 =
        if (reciprocal r1).IsSome then
            if (reciprocal r2).IsSome then
                if (reciprocal r3).IsSome then
                    Some((reciprocal r1).Value + (reciprocal r2).Value + (reciprocal r3).Value)
                else
                    None
            else
                None
        else
            None 

但是,当然,这不是使用CPS--更不用说它看起来真的很麻烦,而且有相当多的重复代码,看起来也像是代码气味。

有人能告诉我如何用CPS的方式重写阻力函数吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-17 01:43:37

简单的方法:

代码语言:javascript
复制
let resistance_cps c1 c2 c3 = 
    let reciprocal_cps r k = k (checkedDiv 1.0 r)
    reciprocal_cps c1 <| 
        function
        | Some rc1 -> 
            reciprocal_cps c2 <| 
                function
                | Some rc2 -> 
                    reciprocal_cps c3 <|
                        function 
                        | Some rc3 -> Some (rc1 + rc2 + rc3)
                        | _ -> None
                | _ -> None
        | _ -> None

或者使用Option.bind时更短一些

代码语言:javascript
复制
let resistance_cps2 c1 c2 c3 = 
    let reciprocal_cps r k = k (checkedDiv 1.0 r)
    reciprocal_cps c1 <|
        Option.bind(fun rc1 -> 
            reciprocal_cps c2 <| 
                Option.bind(fun rc2 ->
                    reciprocal_cps c3 <| 
                        Option.bind(fun rc3 -> Some (rc1 + rc2 + rc3))
                )
        )
票数 3
EN

Stack Overflow用户

发布于 2011-12-17 01:45:23

这是Chris Smith的"Programming F#“一书中的一个已知任务;244页给出了CPS风格的解决方案代码:

代码语言:javascript
复制
let let_with_check result restOfComputation =
    match result with
    | DivByZero -> DivByZero
    | Success(x) -> restOfComputation x

let totalResistance r1 r2 r3 =
    let_with_check (divide 1.0 r1) (fun x ->
    let_with_check (divide 1.0 r2) (fun y ->
    let_with_check (divide 1.0 r3) (fun z ->
    divide 1.0 (x + y + z) ) ) )
票数 2
EN

Stack Overflow用户

发布于 2011-12-17 01:48:05

使用可能由monad定义的here

代码语言:javascript
复制
let resistance r1 r2 r3 =
  maybe {
    let! r1 = reciprocal r1
    let! r2 = reciprocal r2
    let! r3 = reciprocal r3
    return r1 + r2 + r3
  }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8537906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档