IT序号网

f#之如何在 CPS 中编写此内容

zengkefu 2024年11月24日 编程语言 39 0

我正在努力掌握连续传球风格 (CPS),因此我正在修改 Gary Short 很久以前给我看的一个例子。我没有他的示例源代码,所以我试图从内存中修改他的示例。考虑以下代码:

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))));; 

我不太明白的是如何构造阻力函数。我早些时候想到了这个:

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 方式重写阻力函数?

请您参考如下方法:

直接的方式:

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 更短一些

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)) 
                ) 
        ) 


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!