Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No instance for Num String arising from the literal `1'

Tags:

haskell

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.

like image 901
spiros Avatar asked Nov 30 '22 00:11

spiros


2 Answers

"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]
like image 76
leftaroundabout Avatar answered Dec 05 '22 02:12

leftaroundabout


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.

like image 39
Ingo Avatar answered Dec 05 '22 02:12

Ingo