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 ?
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'