无法理解来自非法元组列表的错误消息

时间:2018-07-13 22:48:16

标签: haskell

我知道此元组列表不起作用,因为元组的元素不是同一类型。但是我听不懂错误信息。

Prelude> [(1,2),("One",2)]

<interactive>:1:3: error:
    ? Could not deduce (Num [Char]) arising from the literal ‘1’
      from the context: Num b
        bound by the inferred type of it :: Num b => [([Char], b)]
        at <interactive>:1:1-17
    ? In the expression: 1
      In the expression: (1, 2)
      In the expression: [(1, 2), ("One", 2)]

在这里,我认为Num[Char])代表“一个”。那么,它的含义是“从字面量'1'产生?”是否意味着同一位置的各个元素的类型必须为整数?然后,从上下文中又又意味着什么:Num b?这使我非常困惑。

1 个答案:

答案 0 :(得分:3)

请注意,[1, "One"]已经触发了错误。

我们来剖析错误:关键是

   Could not deduce (Num [Char]) arising from the literal ‘1’

这实际上意味着“我需要使用1 :: [Char],因为这是列表可以输入检查的唯一方法。但是,我不知道如何将文字1解释为[Char]”。 (提醒一下,[Char]String是完全相同的类型,并且都是字符串文字的类型,例如"One"。)

Haskell在处理1之类的数字文字时有点特殊。粗略地认为它们是Integer,是任意精度的整数类型,然后立即使用类型类fromInteger的方法Num转换为所需类型。

class Num a where
   fromInteger :: Integer -> a
   ...

在标准库中,此类具有所有数字类型的实例。用户可以添加其他内容,例如用户定义的数字类型。

一个愚蠢的程序员甚至可以为字符串添加实例!

instance Num [Char] where
   fromInteger n = "urk!" ++ show n

此实例是伪造的,因为它不能合理地定义其他方法,但原则上可以使用。在此实例作用域内,原始代码类型将检查! 我们可以在GHCi中对其进行测试:

> [(1,2),("One",2)]
[("urk!1",2),("One",2)]

请注意Haskell如何按照我们的指示转换文字。

最后的警告:甚至不要考虑将这样的实例添加到严肃的程序中:)类Num应该仅用于数字类型,而字符串不是数字。