Fixed point combinator in Haskell

前端 未结 5 1495
[愿得一人]
[愿得一人] 2020-12-16 16:31

The fixed point combinator doesn\'t always produce the right answer given the definition:

fix f = f (fix f)

The following code does not ter

5条回答
  •  时光取名叫无心
    2020-12-16 16:46

    You probably meant iterate:

    *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]
    

    Here you have all the execution history explicitly available for your analysis. You can attempt to detect the fixed point with

    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)
    

    and then

    *Main> fixed (^2) (0.999 :: Float)
    0.0
    

    but trying fixed (^2) (1.001 :: Float) will loop indefinitely, so you'd need to develop separate testing for convergence, and even then detection of repellent fixed points like 1.0 will need more elaborate investigation.

提交回复
热议问题