main = do
putStrLn $myLast [1,2,3,4]
myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs
When i try to run this code i get this message:
"No instance for (Num String) arising from the literal `1' Possible fix: add an instance declaration for (Num String)"
It runs well when I run with the list ["1","2","3,"4"]. I didn't specify the type but it doesn't work with ints.
"No instance for..." error messages are usually misleading.
The problem you have is simply this
Prelude> :t putStrLn
putStrLn :: String -> IO ()
i.e. that function can only deal with strings, not with numbers. An often-seen solution is to first translate the thing you want to show into a string: putStrLn (show x)
, but actually the combination exists as a much nicer standard function:
main = do
print $ myLast [1,2,3,4]
The compiler concludes from
putStrLn x
that x
must be a String
. The inferred type for
myLast [1,2,3,4]
is Num a => a
and when you now substitute a
with String
you get
Num String => String
This is all quite logical, except that the type checker remembers that the Num
constraint originated from the literal 1
.
The message you get is thus just another way to say that a number is not a string, and putStrLn badly wants a string. Or, if you want, that the expression would be well typed, if only strings were numbers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With