【问题标题】:ERROR: no instance for (Num Char) arising from the literal `1'错误:没有由文字“1”引起的 (Num Char) 实例
【发布时间】:2020-07-04 01:53:29
【问题描述】:

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

testgetting Left 如果n 小于 0

test2 得到Left 如果n 大于xs 的长度或e 类型与列表xs 中的元素类型不匹配。否则将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

【问题讨论】:

  • 小澄清:你到底在问什么?您想知道为什么在帖子末尾出现错误,还是有其他问题?
  • 是的,帖子最后的错误。

标签: haskell monads


【解决方案1】:

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

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

所以编译器看到第一个参数是'a'。这是一个字符,输入Char

“知道了,” - 编译器想, - “现在我知道aChar。现在我知道第二个参数必须有[Char] 类型——即@987654330 的列表@"。

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

幸运的是,数字字面量在 Haskell 中是特殊的。数字文字不仅仅是Int 类型甚至Integer 类型,不!数字可以是 any 类型,只要该类型具有类 Num 的实例即可。

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

但是没有这样的例子!所以编译器正确地抱怨:“没有实例Num Char


要解决此问题,我需要更好地了解您的实际操作。

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

或者您是否打算将其用于角色?那么第二个参数必须是字符列表,而不是数字。

或者您是否不希望前两个参数完全属于同一类型?那么你必须改变sf的类型签名来表明这一点。

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多