Snurka Bill
Snurka Bill

Reputation: 983

Input types in Haskell

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

Answers (3)

sepp2k
sepp2k

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 Integers as arguments, but you're telling read to give you Ints. 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

Paul Visschers
Paul Visschers

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

floAr
floAr

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

Related Questions