0

what's wrong with this code?

module Main where
import System.Environment
main :: IO ()
main = do
    args <- getArgs
    putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1)
    putStrLn(add (read args !! 0) (read args !! 1))
add x y = x + y

Here are the error messages:

main.hs:8:15:
    No instance for (Num String)
      arising from a use of `add'
    Possible fix: add an instance declaration for (Num String)
    In the first argument of `putStrLn', namely
      `(add (read args !! 0) (read args !! 1))'
    In the expression: putStrLn (add (read args !! 0) (read args !! 1))
    In the expression:
      do { args <- getArgs;
           putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1);
           putStrLn (add (read args !! 0) (read args !! 1)) }

main.hs:8:25:
    Couldn't match expected type `Char' with actual type `[Char]'
    Expected type: String
      Actual type: [String]
    In the first argument of `read', namely `args'
    In the first argument of `(!!)', namely `read args'
1
  • Well, what is wrong with it? Errors? Commented Apr 28, 2011 at 10:21

2 Answers 2

8

read args !! 0 should be read (args !! 0) and add x y = x + should be add x y = x + y. Also putStrLn takes a string only, so use print instead which also prints numbers.


However, seeing you are new to haskell. I rewrote part of your program to demonstrate a more haskellish way.

main = do
    (arg0:arg1:restArgs) <- getArgs
    putStrLn $ "Hello, " ++ arg0 ++ ", " ++ arg1
    print $ add (read arg0) (read arg1)
add = (+)

I think it looks a bit cleaner now. Note that it's most often considered bad practice to use !!.

Sign up to request clarification or add additional context in comments.

4 Comments

You need to remove the x y from the pointfree version of add. Good answer otherwise, +1.
That's right amigo. Edited it, sorry for not bothering to compile the code. :)
I think the real reason !! is considered bad practice is because it has undesirable error handling. I might also point out that while your use of pattern matching on the list is more concise than using !!, it has the same dangerous error behavior.
Yes. There are many reasons !! is bad practice, I just wanted to keep it short. The more one studies haskell and thinks about it, the more enlightened conclusion you can draw. As for the asker, I saw it as most appropriate to just give a quick-hint, rather than a complete elaboration on why !! is bad practice. About error handling, I think the error messages will be clearer with pattern matching.
3

Just to add a little elaboration on the error messages and the solution given. Looking at the first error:

    No instance for (Num String)
    ...
    In the first argument of `putStrLn'

This might be a bit unclear. Have a look at the type signature for putStrLn:

putStrLn :: String -> IO ()

So, putStrLn is a function that takes a String and evaluates to an IO action. However you have directly tried to pass putStrLn some expression like (x + y), which is a number, and Strings are not numbers (in Haskell terms, its type signature is (Num t) => t).

The solution given above suggests using the print function instead:

print :: (Show a) => a -> IO ()

The difference between 'print' and 'putStrLn' is that print can take anything showable, which includes numbers.

Next up:

    Couldn't match expected type `Char' with actual type `[Char]'
    Expected type: String
      Actual type: [String]
    In the first argument of `read', namely `args'

This says the compiler expected a String as the first argument to read, but saw a list of Strings. Looking at the original code:

read args !! 0

In Haskell, function application has highest precedence, so the compiler basically reads your code like so:

(read args) !! 0

(note in particular that the application of read binds higher than the use of the !! operator). Hopefully it should be clear now that read has been applied to all of args.

As your intention seemed to be to read the first element of args, you need to use parentheses like so:

read (args !! 0)

Hope this makes the error messages a little more understandable!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.