1

I want to write a simple function that reads a string from console and parses it to a custom data type.

My attempt:

data Custom = A | B Int | C String deriving Read

getFormula::IO Custom
getFormula = do 
    putStrLn("Introduce una formula: ")
    toParse <- getLine
    return read toParse::Custom

But this does not work and I do not know how to interpret the resulting compiling error. How do I fix this? What am I misunderstanding about how IO functions work?


EDIT: This is the error I get when I try to load the file into GCHI

test.hs:7:5:
Couldn't match type ‘String -> a0’ with ‘Custom’
Expected type: String -> Custom
  Actual type: String -> String -> a0
The function ‘return’ is applied to two arguments,
but its type ‘(String -> a0) -> String -> String -> a0’
has only three
In a stmt of a 'do' block: return read toParse :: Custom
In the expression:
  do { putStrLn ("Introduce una formula: ");
       toParse <- getLine;
         return read toParse :: Custom }

test.hs:7:5:
Couldn't match expected type ‘IO Custom’ with actual type ‘Custom’
In a stmt of a 'do' block: return read toParse :: Custom
In the expression:
  do { putStrLn ("Introduce una formula: ");
       toParse <- getLine;
         return read toParse :: Custom }
In an equation for ‘getFormula’:
    getFormula
      = do { putStrLn ("Introduce una formula: ");
             toParse <- getLine;
               return read toParse :: Custom }
1
  • 1
    You could use readLn directly instead getLine and read. Commented Dec 22, 2017 at 20:24

2 Answers 2

2

You have two type errors. The second one is easier to understand:

getFormula::IO Custom

getFormula is declared to have type IO Custom.

    return read toParse::Custom

... but here you claim the last expression has type Custom. IO Custom is not the same as Custom, so the compiler complains.


By the way, your spacing is a bit weird. Why do you have :: jammed right against identifiers on the left and right?

    return read toParse :: Custom

looks less crowded and also less misleading: The :: Custom part applies to the whole expression on the left, not just a single variable.


The first error is a bit confused, but it contains a vital hint: The function ‘return’ is applied to two arguments.

return only takes one argument:

return read toParse

should be

return (read toParse)

In order to also fix the type annotation, you can use one of the following:

  • A bit clunky:

    return (read toParse) :: IO Custom
    
  • Slightly neater (no need to specify IO):

    return (read toParse :: Custom)
    
  • Easiest solution:

    return (read toParse)
    

    You don't need to explicitly specify a type here at all. The compiler already knows you're looking for a Custom because of the getFormula :: IO Custom declaration.

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

Comments

2

The return function has one argument, but you're giving it two - the first one is read, the second one is toParse.

Use parentheses to specify the application order:

return (read toParse :: Custom)

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.