使用fix计算fibonnacci数

时间:2015-08-01 22:51:48

标签: haskell

我试图了解这个因子示例如何使用函数fix :: (a -> a) -> a

Example:

factabs :: (Num a, Eq a) => (a -> a) -> a -> a
factabs fact 0 = 1
factabs fact x = x * fact (x-1)

f :: (Num a, Eq a) => a -> a
f = fix factabs

我不明白为什么fix factabs具有此类型... fix需要类型为a -> a的函数,我们如何将其应用于(a -> a) -> a -> a类型的函数(一个带两个参数的函数)?我完全糊涂了......

基本上我试图弄清楚如何将下面的函数limit转换为使用fix的函数。非常感谢任何帮助。

limit f n
    | n == next       = n
    | otherwise       = limit f next
    where
      next = f n

2 个答案:

答案 0 :(得分:3)

  

fix需要一个a -> a类型的函数,我们如何将它应用于类型为(a -> a) -> a -> a的函数(一个带两个参数的函数)?我完全糊涂了......

这是有效的,因为所有Haskell函数只需要一个参数。即使我们经常想到这种类型......

(a -> a) -> a -> a

...作为两个参数的函数之一,我们也可以像......一样阅读它。

(a -> a) -> (a -> a)

...也就是说,一个函数采用一个参数(一个a -> a函数)并生成一个参数的函数(类型为a)。现在,如果我们采取...

fix :: (b -> b) -> b

...我们可以通过将factabs替换为b来了解(a -> a)如何适合它。

  

基本上我试图弄清楚如何将下面的函数limit转换为使用fix的函数。

您需要做的就是,从原始定义开始,用额外的参数替换limit的任何递归调用,并将此limit - 带有额外参数传递给{{1 (正如您将看到的那样,类型将不再与ado匹配)。

答案 1 :(得分:0)

仅供记录,以下是我在使用limit的问题中发布的fix函数版本:

limit :: Eq a => (a -> a) -> a -> a
limit = fix (\g f x -> let x' = f x
                       in if x == x' then x else g f x')