3
votes

I'm doing sort of a compiler in haskell and I came up to this problem:

This is the code I have for the moment:

data Command a = Input a | Print a

readCommand:: Read a => String -> Command a
readCommand entrada
    | tokens!!0 == "INPUT" = Input (tokens!!1)
    | tokens!!0 == "PRINT" = Print (tokens!!1)
    where
        tokens = words entrada
        listInstr = lines entrada

but I get this error:

Couldn't match type 'a' with 'String'; 'a' is a rigid type variable bound by the type signature for readC:: Read a => String -> Command a

Expected type: [a] ; Actual type: [String]

Does this error mean that if I declare on the function that I have a string, type 'a' cannot be a String too?

Thanks for the help

1
I guess you where looking for ...= Input (read $ tokens!!1) ... which will try read the words/tokens from your input-string into your type aRandom Dev
BTW: maybe you should start with a parser which should handle different types of tokens (data-types) first?Random Dev
PS it means that you promised to return a a but then only produced a String - so if I say readCommand "INPUT 12" :: Command Int you should see the problemRandom Dev
Thank you for your answer, and yes i got many other data-types i just didnt want to post unnecessary info about my problemOuter2g

1 Answers

3
votes

The error means that if you promise a Command a as the result, you must produce a result of type Command a that the caller of your function requests (as long as it meets the condition Read a). So your type signature allows the following code to compile:

x :: Integer
x = readCommand ""

y :: String
y = readCommand ""

z :: [Double]
z = readCommand ""

All of those uses of readCommand are valid according to your type signature, so readCommand needs to be able to produce values of any of those types. The way you defined it, it will always produce a Command String, no matter which type was requested. And since that's not what you promised in your type, you get a compilation error.

If you want to produce Command Strings as your result, you need your type to be readCommand :: String -> Command String. If you want your type to be what it is now, you need to actually produce values of the requested type.

Note that you require Read a, but never actually use the read function, which would be the point of requiring Read a.