Reputation: 3247
This is a program so that the GHC takes a number n from user and then it forms a list of n numbers which again are given by the user. this code is showing some parse error for loop. How can i remove that error?
import System.IO
main = do
putStrLn "Please enter the number"
number <- readLn :: IO Int
putStrLn $ "The num is:" ++ show number
loop number
xs <- sequence [readLn :: IO Int]
putStrLn xs
loop:: Int -> IO ()
loop n = if 0==n then return () else return loop (n-1)
Upvotes: 1
Views: 137
Reputation: 53715
If I understand your intent correctly, you meant to create a "loop" construct that would perform an action n times, and produce a list of the results. In the code you have,
loop number
xs <- sequence [readLn :: IO Int]
But these two statements are separate; you need to instead send the action you wish to be repeated to the loop
as inut:
xs <- loop number readLn :: IO [Int]
Now of course you need to rewrite your loop
to accept an action as a parameter
loop :: Int -> IO a -> IO [a]
loop 0 action = return [] -- don't perform the action
loop n action = do
x <- action -- perform the action once
xs <- loop (n-1) action -- then perform it (n-1) times
return (x:xs) -- produce the resultant list
Here I've written it with pattern matching, instead of if n == 0
. I could just as easily write it with an "if" construct, but I personally tend to find those rather ugly.
But wait, maybe something like this already exists in the standard libraries. Stop...Hoogle time! Hoogling the type signature for our new loop
, a -> IO a -> IO [a], we discover replicateM
.
xs <- replicateM number readLn :: IO [Int]
Upvotes: 0
Reputation: 2392
There are three errors in your code. Copying it and starting it in GHC gives the following messages:
temp.hs:9:13
Couldn't match expected type `Char' with actual type `Int'
Expected type: String
Actual type: [Int]
In the first argument of `putStrLn', namely `xs'
In the expression: putStrLn xs
This one is quite clear. putStrLn
needs a String
, but xs
is a list of Int
s. So simply using print xs
instead of putStrLn xs
solves the problem (print = putStrLn . show
).
The next two are actually about the the same problem:
temp.hs:13:38:
No instance for (Monad ((->) t0))
arising from a use of `return'
Possible fix: add an instance declaration for (Monad ((->) t0))
In the expression: return loop (n - 1)
In the expression:
if 0 == n then return () else return loop (n - 1)
In an equation for `loop':
loop n = if 0 == n then return () else return loop (n - 1)
temp.hs:13:45:
Couldn't match expected type `IO ()'
with actual type `Int -> IO ()'
In the first argument of `return', namely `loop'
In the expression: return loop (n - 1)
In the expression:
if 0 == n then return () else return loop (n - 1)
The problem is in the types. loop
is of type Int -> IO ()
. So the first branch of the function is alright, because you return ()
. However, in the else branch, you return something completely different, because return
is not some built-in statement of the language, but a normal function. So return loop (n - 1)
first lifts your loop
function into the monad and than applies it to (n - 1)
.
Instead, what you want is:
loop n = if n == 0 then return () else loop (n - 1)
Also note that you don't need 0 == n
in Haskell, as there is no way to accidentally use assignment instead of equality comparison (it doesn't compile).
Edit: As the other answers pointed out, loop
isn't really doing anything - it only calls itself n-1 times and then returns ().
Upvotes: 0
Reputation: 47062
In addition to what the other answers have said:
You don't need to write a loop function.
import System.IO
main = do
putStrLn "Please enter the number"
number <- readLn :: IO Int
putStrLn $ "The num is:" ++ show number
xs <- sequence (replicate number (readLn :: IO Int)) -- pay attention to this line
print xs
So we start with readLn
. replicate
makes a list of number
readLn
s. (Depending on your perspective, you might think this is the clever bit.)
The clever bit: sequence
takes that list of IO actions, and turns it into one big IO action. Each readLn
happens in turn, and the return values are collected and returned in a list.
Upvotes: 2