我试图了解这个因子示例如何使用函数fix :: (a -> a) -> a
。
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
答案 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')