Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While loop in Haskell with a condition

I'm having a little Haskell Situation over here. I'm trying to write two functions with monads. First one is supposed to iterate through a function as long as the condition is true for the input / output of the function. Second one is supposed to use the first one to take a number as input and write it as output until you enter a space.

I'm stuck with this, any help?

module Test where

while :: (a -> Bool) -> (a -> IO a) -> a -> IO a
while praed funktion x = do
                         f <- praed (funktion x)
                         if f == True then do
                                             y <- funktion x
                                             while praed funktion y
                         else return x



power2 :: IO ()
power2 = do putStr (Please enter a number.")
            i <- getChar
            while praed funktion
            where praed x = if x /= ' ' then False else True
                  funktion = i
like image 447
Chris Avatar asked Jul 18 '13 09:07

Chris


People also ask

Does Haskell have while loops?

That's why there are no while loops or for loops in Haskell and instead we many times have to use recursion to declare what something is.

What is Haskell take?

Take function is an in-built function in Haskell so that it can be used directly without any import statement, dependency, or any external library. Also on the other hand this function is very easy to use and has very clean syntax as well.


1 Answers

import Control.Monad

while :: (a -> Bool) -> (a -> IO a) -> a -> IO a
while praed funktion x
    | praed x   = do
        y <- funktion x
        while praed funktion y
    | otherwise = return x


power2 :: IO ()
power2 = do
    putStr "Please enter a number."
    i <- getChar
    let praed x = x /= ' '
    let f x = do
        putChar x
        getChar
    while praed f '?'
    return ()

Some notes:

  • Using if x then True else False is redundant, it's equivalent to just x.
  • Similarly if x == True ... is redundant and equivalent to if x ....
  • You need to distinguish between IO actions and their results. For example, if yo do

    do
        i <- getChar
        ...
    

    then in ... i represents the result of the action, a character, so i :: Char. But getChar :: IO Char is the action itself. You can view it as a recipe that returns Char when performed. You can pass the recipe around to functions etc., and it is only performed when executed somewhere.

  • Your while called funktion twice, which probably isn't what you intend - it would read a character twice, check the first one and return the second one. Remember, your funktion is an action, so each time you "invoke" the action (for example by using <- funktion ... in the do notation), the action is run again. So it should rather be something like

    do
        y <- funktion x
        f <- praed y
        -- ...
    

    (My code is somewhat different, it checks the argument that is passed to it.)

like image 189
Petr Avatar answered Sep 22 '22 23:09

Petr