【问题标题】:F# Pattern matching and functionsF# 模式匹配和函数
【发布时间】:2014-12-22 19:08:20
【问题描述】:

我尝试使用这样的模式匹配在 F# 中实现斐波那契数列:

let fibonacci m=
    let rec fib = function
        | (0, _, z) -> z
        | (n, y, z) -> fib (n-1) z (y+z)
    fib m 0 1

在这里,我希望 fib 的第一个参数跟踪我们在序列中的距离,接下来的两个参数是序列中的连续项。

但是,我在 fib (n-1) z (y+z) 上遇到编译时错误:

Type mismatch. Expecting a
    'a -> 'b -> 'c    
but given a
    'c    
The resulting type would be infinite when unifying ''a' and ''b -> 'c -> 'a'

我尝试像这样指定类型:

let fibonacci m=
    let rec fib = function
        | (0, _, z:int) -> z
        | (n:int, y:int, z:int) -> fib (n-1) z (y+z)
    fib m 0 1

然后我在fib (n-1) 上得到一个不同的编译错误:

This value is not a function and cannot be applied

我仍在努力研究函数式编程。我认为问题可能是我对第一个模式的实际含义缺乏理解。我希望它意味着当位置参数为零时,它返回第二个参数项。

有人可以帮我解决这个问题吗,这显然是由于我的一些基本误解

【问题讨论】:

    标签: f# pattern-matching


    【解决方案1】:

    问题是你使用 curried 参数调用函数,而实际上它被定义为期望元组参数:

    let fibonacci m =
        let rec fib = function
            | (0, _, z) -> z
            | (n, y, z) -> fib (n-1, z, y+z)
        fib (m, 0, 1)
    

    这是因为您使用的是function,该模式匹配单个参数,在您的情况下针对元组。另一种方法是使用match

    let fibonacci m =
        let rec fib a b c = 
            match (a, b, c) with
            | (0, _, z) -> z
            | (n, y, z) -> fib (n-1) z (y+z)
        fib m 0 1
    

    您可以将function 视为单个参数函数的简写,然后在该参数上加上match

    【讨论】:

    • 说得对,我猜你只能对单个实体进行真正的模式匹配,而不是参数列表
    • 是的,你可以。请参阅带有 match ... with 示例的更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多