Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Fixed point combinator in Haskell
- fix f = f (fix f)
- fix (x->x*x) 0
- fix f x | f x == f (f x) = f x
- | otherwise = fix f (f x)
- (x -> x * x) ⊥ = ⊥
- Prelude> fix (x->x*x) 0
- <interactive>:1:11:
- No instance for (Num (a0 -> t0))
- arising from a use of `*'
- Possible fix: add an instance declaration for (Num (a0 -> t0))
- In the expression: x * x
- In the first argument of `fix', namely `( x -> x * x)'
- In the expression: fix ( x -> x * x) 0
- f x = if x == 0 then 1 else x * f (x-1)
- f = fix (f' x -> if x == 0 then 1 else x * f' (x-1))
- fix (x->x*x) 0
- let x = x*x in x 0
- sqrt' :: Double -> Double
- sqrt' x = sqrtIter 1.0
- where sqrtIter guess | isGoodEnough guess = guess
- | otherwise = sqrtIter (improve guess)
- improve guess = (guess + x / guess) / 2
- isGoodEnough guess = abs (guess * guess - x) < 0.001
- myFix :: (a -> a) -- "improve" the guess
- -> (a -> Bool) -- determine if a guess is "good enough"
- -> a -- starting guess
- -> a
- fixApprox improve isGoodEnough startGuess = iter startGuess
- where iter guess | isGoodEnough guess = guess
- | otherwise = iter (improve guess)
- sqrt'' :: Double -> Double
- sqrt'' x = myFix improve isGoodEnough 1.0
- where improve guess = (guess + x / guess) / 2
- isGoodEnough guess = abs (guess * guess - x) < 0.001
- primeAfter :: Int -> Int
- primeAfter n = myFix improve isPrime (succ n)
- where improve = succ
- isPrime x = null [z | z <- [2..pred x], x `rem` z == 0]
- myFix f x | f x == f (f x) = f x
- | otherwise = myFix f (f x)
- addG f a b =
- if a == 0 then
- b
- else
- f (a - 1) (b + 1)
- add = fix addG -- Works as expected.
- -- addM = myFix addG (Compile error)
- *Main> take 8 $ iterate (^2) (0.0 ::Float)
- [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
- *Main> take 8 $ iterate (^2) (0.001 ::Float)
- [1.0e-3,1.0000001e-6,1.0000002e-12,1.0000004e-24,0.0,0.0,0.0,0.0]
- *Main> take 8 $ iterate (^2) (0.999 ::Float)
- [0.999,0.99800104,0.9960061,0.9920281,0.9841198,0.96849173,0.93797624,0.8797994]
- *Main> take 8 $ iterate (^2) (1.0 ::Float)
- [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]
- *Main> take 8 $ iterate (^2) (1.001 ::Float)
- [1.001,1.002001,1.0040061,1.0080284,1.0161213,1.0325024,1.0660613,1.1364866]
- fixed f from = snd . head
- . until ((< 1e-16).abs.uncurry (-).head) tail
- $ _S zip tail history
- where history = iterate f from
- _S f g x = f x (g x)
- *Main> fixed (^2) (0.999 :: Float)
- 0.0
Add Comment
Please, Sign In to add comment