0

So as to understand the fix function, from Control.Monad.State, fix :: (a -> a) -> a, I have this little code in modifyValue, that increments an integer until 49, then the function always returns 50.

import Control.Monad.State
type StateVal = Int

modifyValue :: StateVal -> StateVal
modifyValue v | v < 50 = v + 1
modifyValue v = 50

simpleStateStep :: State StateVal ()
simpleStateStep = do
        s <- get
        put $ modifyValue s

main = do
    putStrLn $ show $ fix modifyValue

However when I launch this code, instead of finding the fix point at 50, where the sequence converge to 50... it claims *** Exception: <<loop>>

It is clear that I mistake something since I do not provide an initial state to start the sequence, for example with 1, that would generate [2,3,4,..,49,50,50,50,50....]

Am I using the fix function inappropriately ? Is there something to do so as it can find the fix point 50 ?

duplode
  • 31,361
  • 7
  • 69
  • 130
Stephane Rolland
  • 34,892
  • 31
  • 111
  • 159
  • c.f. http://stackoverflow.com/q/4787421/356440 – Stephane Rolland Feb 18 '17 at 06:39
  • 1
    Formally, `fix` returns the least defined fixed point of a function. `50` is a fixed point, but so is `undefined`: `modifyValue undefined` yields `undefined`. And since `undefined` is less defined than `50`, that's what is returned. `fix` is only useful on functions that don't have `undefined` as a fixed point. – melpomene Jul 15 '19 at 05:35

1 Answers1

2

well fix is defined something like this:

fix f = let x = f x in x

so so it's good to generate recursion for lazy data-structures

fix (1:) == 1:1:1:1:....

which works fine as list are lazy (so take 10 $ fix (1:) is perfectly fine)

It's not so good for pulling out a strict value from a recursive function like yours.

Because as soon as you want to print/evaluate it you need to come up with a value and this will end in an infinite-loop.

You would probably need something like

fixEq f x = let x' = f x in if x' == x then x else fixEq f x'
Carsten
  • 49,407
  • 9
  • 85
  • 111