2014-10-27 68 views
1

我尝试使用模式匹配这样实现在F#Fibonacci序列: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 (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 

我仍然试图让我的头在functiona l编程。我认为问题可能是我对第一种模式的实际含义缺乏了解。我想这意味着当位置参数为零时,它返回第二个参数项。

可能有人能帮我解决这个问题,这显然是因为对我而言有些基本的误解

回答

5

的问题是你打电话的时候,其实是指期待tupled参数咖喱参数的函数:

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这样的说法的简写。

+0

权利是有道理的,我想你只能在一个单一的实体上真正的模式匹配,而不是参数列表 – 2014-10-27 15:14:40

+0

是的,你可以。查看带有匹配...的示例的更新。 – Gustavo 2014-10-27 15:15:32