## DEV Community is a community of 697,080 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Write a simple loop with fix lotz

`fix` (defined in `Data.Function`) is a function that calculates the least fixed point of a function.

``````fix :: (a -> a) -> a
fix f = f (fix f)
``````

For example, the fixed point of a function that always returns "hello" is

``````> fix (const "hello")
"hello"
``````

just "hello". This is because a fixed point is a point where the input and the output of a function become the same.

It is well known that recursive functions can be written as least fixed point of higher-order functions in domain theory.

``````fact :: Int -> Int
fact = fix \$ \f n -> if n == 0 then 1 else n * f (n-1)
``````

## Write a simple loop with fix

You can also use `fix` to write code in your everyday life. For example, let's implement a program that repeats the action of inverting the user's input and outputting it until the input "quit" is received.

``````main :: IO ()
main = do
putStrLn "Start"
fix \$ \loop -> do
str <- getLine
unless (str == "quit") \$ do
putStrLn (reverse str)
loop
putStrLn "Bye"
``````

If you don't use `fix`, you can use `let` to define the recursive function once and then execute it, but I think using fix is cleaner because you can define and execute it at once.

## Give the loop an initial value

Next let's consider an example of setting a limit on the number of loops. Let's make a loop that terminates automatically after 3 loops, even if you don't type "quit".

``````main :: IO ()
main = do
putStrLn "Start"
flip fix 3 \$ \loop n -> do
unless (n == 0) \$ do
str <- getLine
unless (str == "quit") \$ do
putStrLn (reverse str)
loop (n-1)
putStrLn "Bye"
``````

You can give an initial value by flipping a fix. You can see this in the type, as shown below.

``````> :t flip
flip :: (a -> b -> c) -> b -> a -> c

> :t fix
fix :: (a -> a) -> a

> :t flip fix
flip fix :: b -> ((b -> c) -> b -> c) -> c
``````

In other words, you can think of the `fix` type as `((b -> c) -> b -> c) -> b -> c` and `flip`.