Haskell: read and print signatures

read defined in foreplay as

 read :: (Read a) => String -> a 

and can be used as, for example, read "1" :: Int .

Function now

 readOne :: (Read a) => [String] -> (a, [String]) readOne (x:xs) = (read x,xs) 

used with readOne ["1","foo"] results readOne ["1","foo"] (as expected) in error

Ambiguous type variable 'a' in the constraint:
'Read a' arising from a use of 'readOne' at :1:0-18
Probable fix: add a type signature that fixes these type variable(s)

But readOne ["1","foo"] :: Int does not work, but

 readOneInt :: [String] -> (Int, [String]) readOneInt = readOne 

works great:

 > readOneInt ["1", "foo"] (1,["foo"]) 

So: how to add a type signature to readOne without defining a new function of type readOneInt ?

+6
type-inference haskell
source share
1 answer

readOne ["1","foo"] :: Int does not work because readOne cannot return Int , it always returns a tuple whose second element is [String] . readOne ["1", "foo"] :: (Int, [String]) will work.

Note that you only need to specify a type if it cannot be inferred. If you use the readOne result in the context where it should be Int , you can use readOne without type annotations. Example:

 let inc (i, strs) = (i + 1, strs) in inc (readOne ["1", "foo"]) -- (2, ["foo"]) 
+9
source share

All Articles