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]).
Apart from do notation you can also use sequence_ function to execute a series of independent IO actions:
main = sequence_ [putStr $ show $ square 3 ,
putStr $ show $ fibSeries 12]
Related
I have written a Haskell code as:
loop = do
x <- getLine
if x == "0"
then return ()
else do arr <- replicateM (read x :: Int) getLine
let blocks = map (read :: String -> Int) $ words $ unwords arr
putStr "Case X : output = "; -- <- What should X be?
print $ solve $ blockPair blocks;
loop
main = loop
This terminates at 0 input. I also want to print the case number eg. Case 1, 2 ...
Sample run:
1
10 20 30
Case 1: Output = ...
1
6 8 10
Case 2: Output = ...
0
Does anyone know how this can be done? Also, If possible can you suggest me a way to print the output line at the very end?
Thanks in advance.
For the first part of your question, the current case number is an example of some "state" that you want to maintain during the course of your program's execution. In other languages, you'd use a mutable variable, no doubt.
In Haskell, there are several ways to deal with state. One of the simplest (though it is sometimes a little ugly) is to pass the state explicitly as a function parameter, and this will work pretty well given the way you've already structured your code:
main = loop 1
loop n = do
...
putStr ("Case " ++ show n ++ ": Output = ...")
...
loop (n+1) -- update "state" for next loop
The second part of your question is a little more involved. It looks like you wanted a hint instead of a solution. To get you started, let me show you an example of a function that reads lines until the user enters end and then returns the list of all the lines up to but not including end (together with a main function that does something interesting with the lines using mostly pure code):
readToEnd :: IO [String]
readToEnd = do
line <- getLine
if line == "end"
then return []
else do
rest <- readToEnd
return (line:rest)
main = do
lines <- readToEnd
-- now "pure" code makes complex manipulations easy:
putStr $ unlines $
zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
[1..] lines
Edit: I guess you wanted a more direct answer instead of a hint, so the way you would adapt the above approach to reading a list of blocks would be to write something like:
readBlocks :: IO [[Int]]
readBlocks = do
n <- read <$> getLine
if n == 0 then return [] else do
arr <- replicateM n getLine
let block = map read $ words $ unwords arr
blocks <- readBlocks
return (block:blocks)
and then main would look like this:
main = do
blocks <- readBlocks
putStr $ unlines $
zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
[1..] (map (show . solve . blockPair) blocks)
This is similar in spirit to K. A. Buhr's answer (the crucial move is still passing state as a parameter), but factored differently to demonstrate a neat trick. Since IO actions are just normal Haskell values, you can use the loop to build the action which will print the output without executing it:
loop :: (Int, IO ()) -> IO ()
loop (nCase, prnAccum) = do
x <- getLine
if x == "0"
then prnAccum
else do inpLines <- replicateM (read x) getLine
let blocks = map read $ words $ unwords inpLines
prnAccumAndNext = do
prnAccum
putStr $ "Case " ++ show nCase ++ " : output = "
print $ solve $ blockPair blocks
loop (nCase + 1, prnAccumAndNext)
main = loop (1, return ())
Some remarks on the solution above:
prnAccum, the action which prints the results, is threaded through the recursive loop calls just like nCase (I packaged them both in a pair as a matter of style, but it would have worked just as fine if they were passed as separate arguments).
Note how the updated action, prnAccumAndNext, is not directly in the main do block; it is defined in a let block instead. That explains why it is not executed on each iteration, but only at the end of the loop, when the final prnAccum is executed.
As luqui suggests, I have removed the type annotations you used with read. The one at the replicateM call is certainly not necessary, and the other one isn't as well as long as blockPair takes a list of Int as an argument, as it seems to be the case.
Nitpicking: I removed the semicolons, as they are not necessary. Also, if arr refers to "array" it isn't a very appropriate name (as it is a list, and not an array), so I took the liberty to change it into something more descriptive. (You can find some other ideas for useful tricks and style adjustments in K. A. Buhr's answer.)
I have a function blabla in Haskell which takes an Int and returns a string:
blabla :: Int -> [Char]
I want to run that method repeatedly in a for-loop, something like this:
for i := 1 to 25 do begin
write(i);
write(": ");
writeln(blabla(i));
end;
Does haskell have a for loop feature?
There's a forM_ function in the Control.Monad module which is similar to a for loop in imperative programming languages:
import Control.Monad (forM_)
blabla :: Int -> String
blabla = show
main = forM_ [1..25] $ \i -> do
putStr (show i)
putStr ": "
putStrLn (blabla i)
However, I would advise you to stay away from such imperative style code. For example, the same code can be written more succinctly as:
import Control.Monad (mapM_)
blabla :: Int -> String
blabla = show
main = mapM_ (\i -> putStrLn $ show i ++ ": " ++ blabla i) [1..25]
Hope that helps.
Upon drinking a cup of tea I got the best result, I think:
blablaResults = map (\x -> show x ++ ":" ++ blabla x) [0..25]
main = putStrLn $ unlines blablaResults
You're still thinking in a procedural fashion. Try to think in terms of lists, rather than in terms of loops.
Then what you want is a list like this: [1,f(1),2,f(2),3,f(3)...,n,f(n)]
This is where map enters the picture. If you had a function f and wanted to apply it to a list [1,2,3...,n], you use map f [1..n].
What you want is a function that takes a number i and applies a function f to it,then responds with [i,f(i)] or perhaps a tuple (i,f(i)).
So you create this function and map it to your list.
And, of course, you need to create that initial list to operate on - that list from [1..n].
Another approach is to use a list comprehension:
forloop n = [(x,f x)|x <- [1..n] ]
(Note: I have no Haskell compiler with me right now, so I need to verify that last part later. I believe it should work as presented).
I think, I got it by myself:
blablaOutput :: [Int] -> IO()
blablaOutput (x:xs) = do
putStrLn (blabla x)
blablaOutput xs
blablaOutput _ = putStrLn "That's all, folks!"
main = blablaOutput [0..25]
Certainly not very functional in means of functional programming, but it works.
Basically I would like to find a way so that a user can enter the number of test cases and then input their test cases. The program can then run those test cases and print out the results in the order that the test cases appear.
So basically I have main which reads in the number of test cases and inputs it into a function that will read from IO that many times. It looks like this:
main = getLine >>= \tst -> w (read :: String -> Int) tst [[]]
This is the method signature of w: w :: Int -> [[Int]]-> IO ()
So my plan is to read in the number of test cases and have w run a function which takes in each test case and store the result into the [[]] variable. So each list in the list will be an output. w will just run recursively until it reaches 0 and print out each list on a separate line. I'd like to know if there is a better way of doing this since I have to pass in an empty list into w, which seems extraneous.
As #bheklilr mentioned you can't update a value like [[]]. The standard functional approach is to pass an accumulator through a a set of recursive calls. In the following example the acc parameter to the loop function is this accumulator - it consists of all of the output collected so far. At the end of the loop we return it.
myTest :: Int -> [String]
myTest n = [ "output line " ++ show k ++ " for n = " ++ show n | k <- [1..n] ]
main = do
putStr "Enter number of test cases: "
ntests <- fmap read getLine :: IO Int
let loop k acc | k > ntests = return $ reverse acc
loop k acc = do
-- we're on the kth-iteration
putStr $ "Enter parameter for test case " ++ show k ++ ": "
a <- fmap read getLine :: IO Int
let output = myTest a -- run the test
loop (k+1) (output:acc)
allOutput <- loop 1 []
print allOutput
As you get more comfortable with this kind of pattern you'll recognize it as a fold (indeed a monadic fold since we're doing IO) and you can implement it with foldM.
Update: To help explain how fmap works, here are equivalent expressions written without using fmap:
With fmap: Without fmap:
n <- fmap read getLine :: IO [Int] line <- getLine
let n = read line :: Int
vals <- fmap (map read . words) getLine line <- getLine
:: IO [Int] let vals = (map read . words) line :: [Int]
Using fmap allows us to eliminate the intermediate variable line which we never reference again anyway. We still need to provide a type signature so read knows what to do.
The idiomatic way is to use replicateM:
runAllTests :: [[Int]] -> IO ()
runAllTests = {- ... -}
main = do
numTests <- readLn
tests <- replicateM numTests readLn
runAllTests tests
-- or:
-- main = readLn >>= flip replicateM readLn >>= runAllTests
I'm trying to write a program that reads an integer n from the user, then reads n integers (on separate lines), and finally display the sum of the n numbers read.
Here is my code so far:
addNumbers :: IO ()
addNumbers = do
putStrLn "Enter a number:"
num <- getInt
addNumbers2 num
addNumbers2 :: Int -> IO ()
addNumbers2 num = do
putStrLn "Enter a number:"
n <- getInt
if num == 1 then
print n
else do
print (n + addNumbers2 (num - 1))
At the moment it doesn't compile, the error says:
Couldn't match expected type `Int' with actual type `IO ()'
In the return type of a call of `addNumbers2'
In the second argument of `(+)', namely `addNumbers2 (num - 1)'
In the first argument of `print', namely
`(n + addNumbers2 (num - 1))'
IO is really confusing me, I'm trying to get an output of:
Enter a number:
3
Enter a number:
2
Enter a number:
1
Enter a number:
5
Sum is: 8
You treated addNumbers as if it were an ordinary function, but it's an IO operation, so we can only get numbers out of it inside do and with answer <- addNumbers2, but also at the moment it doesn't return anything, it just prints it.
I've refactored a little:
addNumbers :: IO ()
addNumbers = do
putStrLn "Enter how many numbers:" -- clearer
num <- getInt
sum <- addNumbers2 num -- use new version to return sum
print sum -- print them here
and now addNumbers2 actually adds them and returns them:
addNumbers2 :: Int -> IO Int
addNumbers2 num = do
putStrLn "Enter a number:"
n <- getInt
if num == 1 then
return n -- pass the number back
else do
therest <- addNumbers2 (num - 1) -- get the rest of them
return (n + therest) -- add them up
That works:
addNumbers
Enter how many numbers:
3
Enter a number:
1
Enter a number:
2
Enter a number:
3
6
A better way
sequence :: Monad m => [m a] -> m [a] takes a list of actions and runs them all, returning the list of results. If we just make a list full of getInts, [getInt| _<-[1..num]] or more consisely, replicate num getInt we could do numbers <- sequence (replicate num getInt). There's a shorthand for that in Control.Monad, called replicateM :: Monad m => Int -> m a -> m [a]
This would be better done like this though:
import Control.Monad
addNumbers' = do
putStrLn "Enter how many numbers:"
num <- getInt
numbers <- replicateM num (putStrLn "Enter a number" >> getInt)
print (sum numbers)
which gives
Enter how many numbers:
3
Enter a number
10
Enter a number
20
Enter a number
30
60
You can (and should) use combinators available
addNumbers2 n = do
n_numbers <- replicateM n (putStrLn "Number, please: " >> getInt)
let result = sum n_numbers
return result
The crucial insight is to combine the IO actions
putStrLn "string" :: IO ()
getInt :: IO Int
to
(putStrLn "Number?" >> getInt) :: IO Int
So we have a IO action that asks for input and reads it.
Now, we can use
replicateM :: Int -> IO a -> IO [a]
and since we pass an IO action that returns Int, we get a list of Int back.
numbers <- replicateM n (putStrLn "Number?" >> getInt)
runs the given IO action n times and collects their results.
All that is left is summing up the numbers and returning them in the IO Monad.
Or, if you just want to print the sum, you can also
replicateM n (putStrLn "Number?" >> getInt) >>= putStrLn . show . sum
The following pipes-based solution has one tiny advantage over the accepted solution, which is that it will not stack overflow on a large number of lines:
import Pipes
import qualified Pipes.Prelude as Pipes
main = do
numLines <- readLn
total <- Pipes.sum (Pipes.replicateM numLines readLn)
print total
Example use:
$ ./example
3<Enter>
10<Enter>
20<Enter>
30<Enter>
60
I am currently working through SICP with Haskell. Exercise 1.15 asks how many times a function is called. The idea is probably that you should use the substitution method, but I would like to know how to do so in code.
In an imperative language one can keep a global variable and increment it every time the function is called. But how would you go about it in Haskell (or the pure functional way)?
You can use the Writer monad to accomplish this, provided that all of the calls to the function in question can be grouped together into a do block:
import Control.Monad.Writer
myFunc :: Int -> Int -> Writer (Sum Int) Int
myFunc a b = tell (Sum 1) >> return (a + b)
callMyFunc :: ((Int, Int, Int), Sum Int)
callMyFunc = runWriter $ do a <- myFunc 2 3
b <- myFunc 8 7
c <- myFunc 3 5
return (a, b, c)
main = putStrLn $
"myFunc was called "
++ show (getSum $ snd callMyFunc)
++ " times and produced "
++ show (fst callMyFunc)
Which outputs:
myFunc was called 3 times and produced (5,15,8)
It sounds to me like you need to have some kind of counter regardless of whether you go with a functional or a non-functional way. In Haskell, you could use the State Monad to keep track of the state:
import Control.Monad.State
someFunc x = do
num <- get
put (num + 1)
return $ x * x
runSomeFuncs = do
someFunc 1
someFunc 2
someFunc 3
main = do
let (res, state) = runState runSomeFuncs 0
putStrLn ("result: " ++ (show res))
putStrLn ("# of calls: " ++ show state)
Here, you want to keep track of how many times someFunc got called, so we pass an integer in as the state and increment the integer every time the function gets called by using:
num <- get
put (num + 1)
and then increment it by 1 and put it back. If you run this script, it should print
result: 9
# of calls: 3