错误:没有由文字"1"产生的(字符数)实例



insert_at将元素e插入到特定位置xs的列表中n

test如果n小于 0 则Left

test2n大于xs的长度或e的类型与列表xs中的元素类型不匹配,则会Left。否则Right xs传递给下一个。

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)

所有其他错误都得到了妥善处理,期待这个。

* 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

错误消息指出您正在尝试计算表达式sf 'a' [1, 2, 3, 4, ....] 3。由于您的问题中未显示此表达式,因此我假设您在GHCi中使用它来测试您的代码,对吗?

sf的类型签名表示第一个参数的类型为a,第二个参数的类型为[a],这是一个列表,其元素与第一个参数的类型相同。

所以编译器看到第一个参数是'a'。这是一个角色,键入Char.

">

知道了,"-编译器想,-"现在我知道aChar.现在我知道第二个参数必须具有类型[Char]- 即Char列表"。

是的,第二个参数确实是一个列表,但是等等!列表的第一个元素不是字符,而是数字1!这不算!

幸运的是,数字文字在哈斯克尔中很特别。数字文字不仅仅是Int类型,甚至不是Integer类型,不!数字可以是任何类型的,只要该类型具有类Num的实例。

因此,由于编译器已经知道该列表的元素必须是类型Char,但它看到一个数字文字,它得出结论,它现在必须找到类型Char的类Num的实例。

但是没有这样的例子!因此,编译器正确地抱怨:">没有实例Num Char">


为了解决这个问题,我需要更好地了解你实际想要做什么。

您是否打算将整个函数用于数字?然后,第一个参数必须是数字,而不是字符。

还是你打算让它在角色上工作?然后,第二个参数必须是字符列表,而不是数字。

还是您打算将前两个参数根本不是同一类型?然后,您必须更改sf的类型签名以指示这一点。

sf需要一个值和一个列表作为其前两个参数。列表的元素必须与第一个参数具有相同的类型。这就是意思

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

当你写sf 'a' [1]时,这意味着1'a'必须具有相同的类型。因此,类型检查器寻找一种将1解释为Char的方法;它失败了,因为这是不可能的。一些修复可能包括:

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

最新更新