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