Reputation: 983
I would like to ask question. I am biginner in Hakskell and I have some diffictulties with very simple program, which should tell me if divident % divider == 0.
I have this code:
f::Integer -> Integer -> Bool
f x y = if ((x `mod` y) == 0) then True
else False
main = do putStrLn "Set up dividend"
x <- getLine
putStrLn "Set Up divider"
y <- getLine
f read x::Int read y::Int
but when I want to run it, I've got an error:
Couldn't match expected type `Int' with actual type `m0 b0'
Expected type: m0 a0 -> m0 b0 -> Int
Actual type: m0 a0 -> m0 b0 -> m0 b0
In a stmt of a 'do' block: putStrLn "Set up dividend"
In the expression:
do { putStrLn "Set up dividend";
x <- getLine;
putStrLn "Set Up divider";
y <- getLine;
.... } ::
Int
and I have really no idea, what is wrong. I've also tried f x y (not f read x::Int .....)
without any results. I must do something wrong. I know there are many topics about this problem, but nothing helped me. I am missing something.
Upvotes: 1
Views: 213
Reputation: 370417
f read x::Int read y::Int
This applies the function f
to the arguments read
, x
, read
and y
. It's also saying that the result of f read y
should be an Int
and that result of the whole thing should be an Int
as well. That's obviously not what you want. What you want is to apply f
to the results of read x
and read y
, so you need parentheses around those.
Another problem is that f
takes Integer
s as arguments, but you're telling read
to give you Int
s. You can fix that by changing Int
to Integer
or you can remove the type annotations altogether as they can be inferred. You could also change the type of f
to accept any type of Integral
, so that it works with both Int
and Integer
.
Lastly the type of main
needs to be IO ()
, but your definition evaluates to a Bool
. Maybe you want to print the Bool
?
The combination of getLine
and read
can be simplified to readLine
by the way.
So you could do:
main = do putStrLn "Set up dividend"
x <- readLine
putStrLn "Set Up divider"
y <- readLine
print $ f x y
Upvotes: 6
Reputation: 584
The problem is in your final line:
f read x::Int read y::Int
This code is basically saying f read x read y
, which is of type Int
and where f read x
is also of type Int
. You have to add parentheses so that f
is applied properly and that the type annotations are used on the correct terms. You get:
f ((read x) :: Int) ((read y) :: Int)
-- or with fewer parentheses, but meaning the same thing:
f (read x :: Int) (read y :: Int)
Also the if-statement in your definition of f
is unnecessary, why not use:
f x y = (x `mod` y) == 0
Upvotes: 7
Reputation: 829
On a first glance you need to use f (read x::Int) (read y::Int)
because in your case you are passing functions to you f. I suggest you to take a look at Learn you Haskell for gread good, the input/output chapter in detail. It is one of the best, newbie friendly ressources out there as far as I know.
Upvotes: 0