user13101912
user13101912

Reputation:

ERROR: no instance for (Num Char) arising from the literal `1'

insert_at insert an element e into a list xs in specific location n

testgetting Left if n less than 0

test2 getting Left if n larger than xs's length or The type e isn't match the element's type in listxs. Otherwise passing Right xs to the next.

import Data.Typeable

insert_at :: a -> [a] -> Int -> [a]
insert_at e xs n = a++(e:b) where
    t = splitAt n xs
    a = fst t
    b = snd t 
test :: (Ord a, Num a) => b -> a -> Either [Char] b
test xs n = if n < 0 then Left "n<0" else Right xs

test2 :: (Typeable a1, Typeable a2) =>
           a1 -> [a2] -> Int -> Either [Char] [a2]
test2 e xs n 
        | n> ( length xs )= Left "n> $ length xs "
        | (typeOf e) /= (typeOf (head xs) ) = Left "(typeOf e) /= (typeOf (head xs) ) "
        |otherwise = Right xs

sf :: Typeable a => a -> [a] -> Int -> Either [Char] [a]
sf e xs n = test xs n >>test2 e xs n >> Right (insert_at e xs n)

All the other error got properly handled, expect this.

* No instance for (Num Char) arising from the literal `1'
    * In the expression: 1
      In the second argument of `sf', namely `[1, 2, 3, 4, ....]'
      In the expression: sf 'a' [1, 2, 3, 4, ....] 3

Upvotes: 0

Views: 1009

Answers (2)

Fyodor Soikin
Fyodor Soikin

Reputation: 80714

The error message states that you're trying to evaluate the expression sf 'a' [1, 2, 3, 4, ....] 3. Since this expression is not shown in your question, I'm assuming you're using it in GHCi to test out your code, right?

The type signature of sf says that the first parameter has type a, and the second parameter has type [a], which is a list whose elements are of the same type as the first parameter.

So the compiler sees that the first parameter is 'a'. That's a character, type Char.

"Got it," - thinks the compiler, - "now I know that a is Char. And now I know that the second parameter must have type [Char] - that is, a list of Char".

And yes, the second parameter is indeed a list, but wait! The first element of the list is not a character, but number 1! That does not compute!

Fortunately, number literals are special in Haskell. Number literals are not merely of type Int or even of type Integer, no! Numbers can be of any type as long as that type has an instance of class Num.

So since the compiler already knows that the elements of that list must be of type Char, but it sees a number literal, it concludes that it must now find an instance of class Num for type Char.

But there is no such instance! And so the compiler rightly complains: "no instance Num Char"


To fix the problem, I need to better understand what you were actually trying to do.

Did you intend the whole function to work on numbers? Then the first parameter must be a number, not a character.

Or did you intend it to work on characters? Then the second parameter must be a list of characters, not numbers.

Or did you intend the first two parameters not to be the same type at all? Then you must change the type signature of sf to indicate that.

Upvotes: 2

Daniel Wagner
Daniel Wagner

Reputation: 152682

sf expects a value and a list as its first two arguments. The elements of the list must have the same type as the first argument. This is the meaning of

sf :: a -> [a] -> ...

When you write sf 'a' [1], this means 1 and 'a' must have the same type. So the type checker looks for a way to interpret 1 as a Char; it fails, because this is not possible. Some fixes might include:

sf 'a' "1234" 3
sf 'a' [toEnum 1, toEnum 2, toEnum 3, toEnum 4] 3
sf (fromEnum 'a') [1, 2, 3, 4] 3

Upvotes: 0

Related Questions