Haskell表达式修复函数

时间:2016-11-19 16:54:19

标签: haskell recursion induction

所以我正在阅读Paul Hudak的书“The Haskell School of Expression”,并坚持在那里练习。

这就是

假设功能修复定义为

fix f = f (fix f)

修复的主要类型是什么。那个我知道的,它的b - > b - > B'/ P>

但是我不明白定义修复的方式,它不会进入无限递归吗?

还要将余数函数定义为

remainder :: Integer -> Integer -> Integer
remainder a b = if a < b then a 
                else remainder (a - b) b 

使用fix重写余数,使其不是递归的。

2 个答案:

答案 0 :(得分:2)

首先,主要类型的修复实际上是(b -> b) -> b(请记住,只有b -> (b -> b)b -> b -> b相同)。

在严格的语言中,这样的定义会进入无限递归,但由于Haskell是惰性的,因此只有在需要任何点时才会计算函数的参数。例如,您可以定义factorial

-- with recursion
factorial :: Int -> Int
factorial n = if n == 0 then 1 else n * factorial (n-1)

-- with `fix`
factorial' :: Int -> Int
factorial' = fix (\f n -> if n == 0 then 1 else n * f (n - 1))

遵循相同的模式,您应该能够定义remainder

答案 1 :(得分:1)

稍微玩一下给我们

fix f         = f (fix f)                                            -- definition
fix f     a   = f (fix f) a                                          -- eta expansion
fix f     a b = f (fix f) a b                                        -- eta expansion
remainder a b = if a < b then a else remainder (a - b) b             -- definition
-- we want  remainder = fix f:                                       -- equation
fix f     a b = if a < b then a else (fix f)   (a - b) b             -- substitution
       = (\g -> if a < b then a else g         (a - b) b) (fix f)    -- abstraction
   = fix (\g -> \a b -> if a < b then a else g (a - b) b) a b        -- abstraction

从而

remainder = 
     fix (\g     a b -> if a < b then a else g (a - b) b)            -- eta reduction