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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.