No instance for Num String arising from the literal `1' - 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.

"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.

putStrLn has type String -> IO () so you need to convert your list element into a string first.
You can do this with show:
putStrLn $ show $ myLast [1,2,3,4]

Related

Haskell. Matching pattern Problem. Cannot put in IO value of function with empty list "print $ note1 []" - failing to compile

Haskell. Matching pattern Problem. Cannot put in IO value of function with empty list
print $ note1 []
failing to compile, but works fine in ghci ?!
Also the print $ note1 [1] works fine and compiles fine too. The problem only with empty list:
print $ note1 []
(N.B. I am new in Haskell)
I
have a matching pattern function
note1 :: (Show a) => [a] -> String
note1 [] = "Empty"
note1 (x:[]) = "One"
But print $ note1 [] fails to compile, but perfectly works in ghci interpreter?!
I am using stack 2.3.1 and ghc 8.8.3 on MacOS.
This is the compilation error produced by compiler.
/Users/admin1/Haskell/PROJECTS/orig1/src/Lib.hs:18:13: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘note1’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 15 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the second argument of ‘($)’, namely ‘note1 []’
In a stmt of a 'do' block: print $ note1 []
In the expression:
do putStrLn "someFunc"
putStrLn $ show (1)
putStrLn $ show $ length ("a" :: String)
putStrLn $ show (length' "a")
.... |
18 | print $ note1 []
The problem is the (unnecessary, in this case) Show a constraint on note1. Here's what happens. When GHC is typechecking print $ note1 [], it needs to work out which Show instance to use with note1. That's typically inferred from the type of elements in the list that it's passed. But the list it's passed ... doesn't have any elements. So the typechecker has no particular way to choose an instance, and just gives up. The reason this works in GHCi is that GHCi, by default, enables the ExtendedDefaultRules language extension, which expands the type defaulting rules. So instead of throwing up its hands, the type checker picks the type () for elements of the list, and everything works. Something sort of similar is going on when you use [1]. In that case, the standard defaulting rule comes into play: numeric types default to Integer, so the typechecker picks that type.
How should you fix this? You could manually write
print $ note1 ([] :: [()])
to make your code compile, but if that's your real code, you'd be much better off removing the unnecessary constraint:
note1 :: [a] -> String
note1 [] = "Empty"
note1 (x:[]) = "One"
As a side note, since you don't use the x variable, it's best to make that fact explicit by either using the special _ pattern:
note1 :: [a] -> String
note1 [] = "Empty"
note1 (_:[]) = "One"
or prefixing the variable name with an underscore:
note1 :: [a] -> String
note1 [] = "Empty"
note1 (_x:[]) = "One"
This indicates, both to other programmers (such as yourself a few hours later) and the compiler, that you are intentionally not using that value.
Additionally, you can (and probably should) use list syntax to clarify the second pattern:
note1 [_] = "One"
Finally, the note1 function has a bit of a problem: if you pass it a list with more than one element, it'll produce a pattern match failure. Whoops! It's usually better to write total functions when you can. When you can't, it's generally best to use an explicit error call to indicate what went wrong. I recommend compiling your code with the -Wall flag to help catch mistakes.

Read list of unknown type from user input Haskell:

Say I have the following function:
readList :: IO [Int]
readList = do
putStrLn "Please enter the list as a string"
putStrLn "Example: input of '1 2 3 4 5' will map to [1,2,3,4,5]"
line <- getLine
return $ map read $ words line
printNaive :: [Int] -> IO ()
printNaive xs = putStrLn "The maximum surpasser count is:" >> putStrLn "0"
main :: IO ()
main = readList >>= printNaive
This function works as expected. Now lets say I was going to extend this code to be more generic, and read in a line of any type of thing as a list:
readList :: (Read a, Int a) -> IO [a]
readList = do
putStrLn "Please enter the list as a string"
putStrLn "Example: input of '1 2 3 4 5' will map to [1,2,3,4,5]"
line <- getLine
return $ map read $ words line
printNaive :: (Eq a) => [a] -> IO ()
printNaive xs = putStrLn "The maximum surpasser count is:" >> putStrLn "0"
main :: IO ()
main = readList >>= printNaive
This fails with:
Ambiguous type variable ‘a0’ arising from a use of ‘Lib.readList’
prevents the constraint ‘(Read a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Read Ordering -- Defined in ‘GHC.Read’
instance Read Integer -- Defined in ‘GHC.Read’
instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’
...plus 22 others
...plus four instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
How would I go about writing this code, given I really don't care what type of thing it is as long as it conforms to Eq.
Additionally, say I wanted to provide a facility to specify what type the list is going to contain. (through another getLine say).
How would I extract a type from getLine, and how would I then cast every element in the map read $ words line to that particular type.
What you did wrong is in this line:
readList :: (Read a, Int a) -> IO [a]
What you probably want to get at with (Read a, Int a) is a type class constranit for the type a, meaning you want it to be readable and you want it to be some sort of integer.
Firstly you wrote your constraint wrong. A typeclass constraint is given before a => not a ->. Secondly Int is not a type class. Maybe try using Integral?
So your type signature should look like this:
readList :: (Read a, Integral a) => IO [a]
EDIT: A caveat is, however, that the a in the type signature has to be decided at compile time. In the first example in your question it would work out because the type of printNaive fixes a to be Int. That is not generally the case, however.

Getting Result of IO Monad in ghci

Given:
Prelude> let x = return 100 :: IO Int
Trying to evaluate x returns its wrapped value.
Prelude> x
100
But, I can't get its value via show.
Prelude> show x
<interactive>:4:1:
No instance for (Show (IO Int)) arising from a use of ‘show’
In the expression: show x
In an equation for ‘it’: it = show x
What's going on when I type x in ghci?
If you enter an expression of type IO t into GHCi, it unwraps it and prints the resulting value. That is if you enter ioExp, GHCi executes val <- ioExp; print val (whereas if you enter a non-IO expression exp, GHCi executes print exp).
You can't show an IO Int action. The action may require to perform side effects to produce the Int, such as asking the user for such number. Instead, the type of show promises to return a String, i.e. a plain, pure string without any side effect.
You can define your own effectful variant of show, if you want:
showIO :: Show a => IO a -> IO String
showIO = fmap show
Note how the result above is not a plain string, but is wrapped inside the IO monad, as it should be.

Specify list type for input

I'm learning Haskell and I've decided to to the H-99 problem set. Naturally, I've become stuck on the first problem!
I have the following code:
module Main where
getLast [] = []
getLast x = x !! ((length x) - 1)
main = do
putStrLn "Enter a list:"
x <- readLn
print (getLast x)
Compiling this code gives the following error:
h-1.hs:8:14:
No instance for (Read a0) arising from a use of `readLn'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Read () -- Defined in `GHC.Read'
instance (Read a, Read b) => Read (a, b) -- Defined in `GHC.Read'
instance (Read a, Read b, Read c) => Read (a, b, c)
-- Defined in `GHC.Read'
...plus 25 others
In a stmt of a 'do' block: x <- readLn
In the expression:
do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
In an equation for `main':
main
= do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
h-1.hs:9:9:
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 26 others
In a stmt of a 'do' block: print (getLast x)
In the expression:
do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
In an equation for `main':
main
= do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
That's a large error, but it seems to me that Haskell isn't sure what the input type will be. That's fine, and completely understandable. However, as this is supposed to work on a list of generics, I'm not sure how to specify that type. I tried this:
x :: [a] <- readLn
...as [a] is the type that Haskell returns for an empty list (found with :t []). This won't compile either.
As I'm a beginner, I know there's a lot I'm missing, but in a basic sense - how can I satisfy Haskell's type system with input code? I'm a Haskell beginner looking for a beginner answer, if that's at all possible. (Also, note that I know there's a better way to do this problem (reverse, head) but this is the way I came up with first, and I'd like to see if I can make it work.)
You can't hope to write something like this which will detect the type of x at run time -- what kind of thing you're reading must be known at compile time. That's why #Sibi's answer uses [Int]. If it can't be deduced, you get a compile time error.
If you want a polymorphic read, you have to construct your own parser which lists the readable types.
maybeDo :: (Monad m) => Maybe a -> (a -> m b) -> m b
maybeDo f Nothing = return ()
maybeDo f (Just x) = f x
main = do
str <- getLine
maybeDo (maybeRead str :: Maybe Int) $ \i ->
putStrLn $ "Got an Int: " ++ show i
maybeDo (maybeRead str :: Maybe String) $ \s ->
putStrLn $ "Got a String: " ++ show s
There are lots of ways to factor out this repetition, but at some point you'll have to list all the types you'll accept.
(An easy way to see the problem is to define a new type MyInt which has the same Read instance as Int -- then how do we know whether read "42" should return an Int or a MyInt?)
This should work:
getLast :: Num a => [a] -> a
getLast [] = 0
getLast x = x !! ((length x) - 1)
main = do
putStrLn "Enter a list:"
x <- readLn :: IO [Int]
print (getLast x)
why return 0 for an empty list, instead of an empty list?
Because it won't typecheck. Because you are returning [] for empty list and for other cases you are returning the element inside the list i.e a. Now since a type is not equal to list, it won't typecheck. A better design would be to catch this type of situation using the Maybe datatype.
Also, because of returning 0, the above function will work only for List of types which have Num instances created for them. You can alleviate that problem using error function.
However, this should work for a generic list, not just a list of Ints
or Numbers, right?
Yes, it should work for a polymorphic list. And you can create a function like getLast which will work for all type of List. But when you want to get input from the user, it should know what type of input you are giving. Because the typechecker won't be able to know whether you meant it as List of Int or List of Double or so on.

No instance for (Show a0) arising from a use of `print' The type variable `a0' is ambiguous

data NestedList a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem element) = [element]
flatten (List []) = []
flatten (List (first:rest)) = flatten first ++ flatten (List (rest))
main = print $ flatten $ List []
I wrote the above seen code in haskell. When I execute this with any other parameter, for example
main = print $ flatten $ List [Elem 1, Elem 2]
main = print $ flatten $ Elem 1
It gives
[1, 2]
[1]
respectively.
It fails when I execute it with an empty List.
main = print $ flatten $ List []
Error message
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 23 others
In the expression: print
In the expression: print $ flatten $ List []
In an equation for `main': main = print $ flatten $ List []
Questions
Why does it fail and how can I fix this?
Should I change my NestedList definition to accept an empty List? If so, how do I do that. Its quite confusing.
The list type is polymorphic. Since you don't supply an element, just the empty list constructor [], there's no way to infer what list type this is.
Is it: [] :: [Int]
or [] :: [Maybe (Either String Double)]. Who's to say?
You are. Supply a type annotation to resolve the polymorphism, then GHC can dispatch to the correct show instance.
E.g.
main = print $ flatten $ List ([] :: [Int])
To add to the answers here already, you may object "but what does it matter what type of things my list contains? it doesn't have any of them in it!"
Well, first of all, it is easy to construct situations in which it's unclear whether or not the list is empty, and anyway type checking hates to look at values, it only wants to look at types. This keeps things simpler, because it means that when it comes to deal with values, you can be sure you already know all the types.
Second of all, it actually does matter what kind of list it is, even if it's empty:
ghci> print ([] :: [Int])
[]
ghci> print ([] :: [Char])
""
The problem is the compiler can't know the type of flatten $ List []. Try to figure out the type yourself, you'll see it's [a] for some a, whilst print requires its argument to be an instance of Show, and [a] is an instance of Show if a is an instance of Show. Even though your list is empty, so there's no need for any constraint on a to represent [], there's no way for the compiler to know.
As such, putting an explicit type annotation (for any type for which an instance of Show exists) should work:
main = print $ flatten $ List ([] :: [NestedList Int])
or
main = print $ flatten $ List ([] :: [NestedList ()])
or
main = print fl
where
fl :: [()]
fl = flatten $ List []
[] can be a list of floats, strings, booleans or actually any type at all. Thus, print does not know which instance of show to use.
Do as the error message says and give an explicit type, as in ([] :: [Int]).

Resources