f#:使用“匹配/有”块没有“with”

时间:2015-08-08 06:20:28

标签: f#

我在f#中编写一个函数,可以使用几个if / else块来完成,但是使用match / with子句读取更清晰。问题是在很多情况下,我并不关心实际匹配的变量;我在所有地方使用“什么时候”。

问题是,有没有办法只使用“when”块并且没有实际的匹配变量来进行“匹配/匹配”?

let primes (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
        match input' with
        | _ when input' = 1I -> acc
        | _ when input = factor -> factor::acc
        | _ when input' = factor -> factor::acc
        | _ when input' % factor = 0I -> factor::factors acc (input'/factor, factor)
        | _ -> factors acc (input', factor+1I)
    in factors [] (input, 2I)

primes 1I |> List.iter (printf "%A "); printfn "..";    
primes 12I |> List.iter (printf "%A "); printfn "..";
primes 60I |> List.iter (printf "%A "); printfn "..";
primes 420I |> List.iter (printf "%A "); printfn "..";
primes 1260I |> List.iter (printf "%A "); printfn "..";
primes 13I |> List.iter (printf "%A "); printfn "..";

[编辑]有人建议这是与this相同的问题,我想是的。但如果不是这篇文章,我就不会看到卡斯滕的答案,这就是我以为我在寻找的东西。现在我知道了,我想这两个选择如下

let primes (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
        match () with
        | () when input' = 1I           -> acc
        | () when input = factor        -> factor::acc
        | () when input' = factor       -> factor::acc
        | () when input' % factor = 0I  -> factor::factors acc (input'/factor, factor)
        | _ -> factors acc (input', factor+1I)
    in factors [] (input, 2I)

let primes' (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
        if   input' = 1I            then acc
        elif input = factor         then factor::acc
        elif input' = factor        then factor::acc
        elif input' % factor = 0I   then factor::factors acc (input'/factor, factor)
        else factors acc (input', factor+1I)
    in factors [] (input, 2I)

像这样并排地看着他们让我觉得我应该使用elif's。

2 个答案:

答案 0 :(得分:2)

此处提供的条件涉及不同的输入,因此无法匹配。这些是elif链更简洁的情况。但是,您可以使用稍短的let primes (input:bigint) = let rec factors acc (input':bigint, factor:bigint) = if input' = 1I then acc elif input = factor then factor::acc elif input' = factor then factor::acc elif input' % factor = 0I then factor::factors acc (input'/factor, factor) else factors acc (input', factor+1I) in factors [] (input, 2I) 关键字:

{{1}}

当你有一个单个输入可以有各种不同的风格或形状时,模式匹配很有价值,但在这种情况下,你宁愿有各种不同的输入,其中它们之间的关系决定了分支,以分层的方式。

答案 1 :(得分:1)

嗯,你可以使用活动模式,但我觉得在这种情况下它的开销太大了 - 如果不是你不能真正逃脱when这里(或者至少我不是意识到的任何方式。)

有一个模式会使这一点变得更加明显(您不必关心仅与match () with | () when ... -> ... | () when ... -> ... | _ -> ... 子句匹配的值):

<script type="text/javascript">
    function codeAddress(){ 
         var data = <%- jsonData %>;
         document.write(JSON.stringify(data)); 
    }
</script>
你可能已经看过了。