1

I am writing my first Haskell program and I am having difficulties in making a function use a user-entered input value. I don't yet understand enough about the language, so I started off simply, by creating a function that reads in a user-input value and returns this as an integer. Then, in the main calling function I want to use this value as the input to another function. This is the code scenario:

module Main where

square :: Int -> Int
square n = n*n  

getInt :: IO Integer
getInt = do
    putStrLn "Enter a positive integer: "
    s <- getLine
    putStrLn("The number you entered is " ++ s)
    let num = read s :: Integer
    return num

main :: IO ()
main = do 
    num <- getInt
    print num -- works
    print $ square (getInt) -- breaks down here
    print $ square (num) -- also does not work
    print $ square (5) -- works
0

2 Answers 2

6

Mismatch between Int and Integer

Let's look at the signatures here:

square :: Int -> Int
getInt :: IO Integer

It's clear that Int is not an Integer, so choose either, or use Num n => n:

square :: Num n => n -> n
getInt :: Num n => IO n

Mismatch between Int and IO Int

The second problem is a bit more complicated. Since getInt is an IO action, it needs to be extracted first to be used:

num <- getInt
print $ square num

There are other ways to compose a pure function with an IO action:

-- Control.Applicative (<$>)
square <$> getInt >>= print

-- Data.Functor (fmap)
fmap square getInt >>= print

-- directly composed with return
getInt >>= return . square >>= print

-- manual lambda extraction
getInt >>= (\x -> return $ square x) >>= print
Sign up to request clarification or add additional context in comments.

3 Comments

Actually, none of the last 4 examples type check.
@chi I wrote that a bit too hastily. Fixed now.
Also the initial two signatures are not displayed as code (missing indentation). I would write an edit, but spaces do not count as characters apparently (so my edit won't go through).
2

There are two things going on here.

Firstly, the reason you cannot do print $ square getInt is because getInt has the type IO Integer - you should extract the value via num <- getInt first, before running functions that can take and receive Integers.

The second is that you are actually using two different integer types in your program, and Haskell does not automatically coerce between them. Notice that getInt :: IO Integer whilst square :: Int -> Int. If you were to change the types to be consistent, your line print $ square num would work. The square function expects an Int, whilst you are giving it num, which is an Integer. The difference between these two types is that Int is bounded, as a machine integer, whilst Integer is unbounded.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.