Reputation: 11
I am having trouble trying to convert the following block of C code into Haskell.
void echo(int num){
if(num != 0)
print(num)
else
exit()
}
I just started learning Haskell, but I am pretty confused as to how such a simple function could be so difficult.
Upvotes: 0
Views: 104
Reputation: 54078
What makes it seem difficult in Haskell is that the type system forces you to separate these kinds of functions from those that do not alter the state of the machine, such as printing to the screen or exiting the program. In order to write a function like this you have to use the IO
monad:
import System.Exit -- Need this for exitSuccess
-- v The () is like void
echo :: Int -> IO ()
echo n =
if n /= 0
then print n
else exitSuccess
As you can see, there's nothing inherently more complex about this definition in Haskell than in the C-style languages. You just have to import the module that contains the function used to exit, and you have to write your function to work in the IO
monad. You can use this function in a program as
loop :: IO ()
loop = do
putStr "Enter a number: "
numStr <- getLine
echo (read numStr)
loop
main :: IO ()
main = loop
This short snippet of code will continuously prompt the user for a number, then echo it back unless they enter 0
.
I mentioned at the beginning of this answer that the type system doesn't let you mix state altering code with non-state altering code. How does it do this? In this case, any function with a type signature that ends with IO a
(where a
can be anything) executes in the IO
monad, and only in that monad context. So you can't do something like
doubler :: Int -> Int
double n = 2 * (echo n)
This won't type check! 2 *
expects the next argument to be an Int
, whereas echo n
has the type IO ()
. Even if it had the type IO Int
, this is not the same as or compatible with the type Int
. If instead you had
doubler :: Int -> IO Int
doubler n = do
echo n
return (2 * n)
You could then use it as
loop :: IO ()
loop = do
putStr "Enter a number: "
numStr <- getLine
nDoubled <- doubler (read numStr)
putStr "Your number doubled is "
print nDoubled
loop
Obviously, this will echo the original number, or exit the program if it's 0, then print Your number doubled is <n>
where <n>
is the new number, and then repeat this process until a 0 is entered.
Upvotes: 10