I'm new to Haskell and I am wondering how can I print the results of two functions in Haskell, something I would do in c++ like:
cout << f() << g();
Or in c#:
Console.WriteLine(f() + " " + g());
In Haskell I tried something like
main =
--putStr ( show $ square 3 )
putStr ( show $ fibSeries 12 )
square :: Int -> Int
square x = x * x
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
fibSeries :: Int -> [Int]
fibSeries x = map fib [0..x]
but I had to comment the first command because it has given me a compile-time error.
The error is:
src\Main.hs:21:5:
Couldn't match expected type `(String -> IO ()) -> String -> t0'
with actual type `IO ()'
The function `putStr' is applied to three arguments,
but its type `String -> IO ()' has only one
In the expression:
putStr (show $ square 3) putStr (show $ fibSeries 12)
In an equation for `main':
main = putStr (show $ square 3) putStr (show $ fibSeries 12)
tl;dr You're so close!
main = do
putStr ( show $ square 3 )
putStr ( show $ fibSeries 12 )
Note that this won't put in any whitespace, you may wish to insert putStr " "
.
Here's what's going on: Haskell's main part, the purely functional language, doesn't have any such thing as "order of computation / action". If you write two lines with statements like print 5
, they're just parsed as one line, namely
print 5 print 5
which means the following: print
is a function that takes the arguments 5
, print
, and 5
, and returns the type of main
(an IO
action). So the type would need to be something like
type PrintType = Int -> PrintType -> Int -> IO()
which is of course nonsense. To tell Haskell you actually want to sequence a chain of actions (what you do all the time in imperative languages, but need much more seldom in functional programming), we have this nice do
notation, which works a lot (but not always quite!) like you'd expect from an imperative standpoint.
To understand how that really works, you need to learn about monads. Those are explained in any decent Haskell tutorial. Read LYAH or something.
Further notes on your code: there's not much point in doing such a printing job sequentially, really. You can just produce a string with all the information you want, and then print that in one go:
main = putStrLn $ show (square 3) ++ " " ++ show (fibSeries 12)
or, if you're not so much interested in formatting but just in getting the information,
main = print ( square 3, fibSeries 12 )
which will result in the output (9,[0,1,1,2,3,5,8,13,21,34,55,89,144])
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With