为什么 Char 没有类似于数字的 `Char a => a`(`Num a => a`)?

Inn*_*nzo 5 haskell types

我不明白为什么当我查看类型时,例如:a = (1, 2) 我得到

a :: (Num a, Num b) => (a, b)
Run Code Online (Sandbox Code Playgroud)

相反,如果我查看以下类型:b = ('a', 'b')我得到

b :: (Char, Char)
Run Code Online (Sandbox Code Playgroud)

而不是类似的东西:

b :: (Char a, Char b) => (a, b)
Run Code Online (Sandbox Code Playgroud)

che*_*ner 6

Haskell 有两种类型的文字:单态和多态。(虽然这样说可能更准确,但文字可以计算为单态或多态类型的值。)

\n

'c'是单态文字的一个例子;它是单一类型的值,即Char.

\n
> :t 'c'\n'c' :: Char\n
Run Code Online (Sandbox Code Playgroud)\n

1另一方面,是一个多态文字。它可以是具有实例的任何类型的值Num

\n
> :t 1\n1 :: Num p => p\n> :t 1 :: Int\n1 :: Int :: Int\n> > :t 1 :: Char\n\n<interactive>:1:1: error:\n    \xe2\x80\xa2 No instance for (Num Char) arising from the literal \xe2\x80\x981\xe2\x80\x99\n    \xe2\x80\xa2 In the expression: 1 :: Char\n
Run Code Online (Sandbox Code Playgroud)\n

其他多态文字包括

\n
    \n
  1. 浮点文字

    \n
    > :t 3.4\n3.4 :: Fractional p => p\n
    Run Code Online (Sandbox Code Playgroud)\n
  2. \n
  3. OverloadedStrings启用扩展时的字符串文字。

    \n
     > :t "foo"\n "foo" :: [Char]\n > :set -XOverloadedStrings\n > :t "foo"\n "foo" :: Data.String.IsString p => p\n
    Run Code Online (Sandbox Code Playgroud)\n
  4. \n
  5. OverloadedLists启用扩展时列出文字。

    \n
    > :t ['a', 'b']\n['a', 'b'] :: [Char]\n> :set -XOverloadedLists\n> :t ['a', 'b']\n['a', 'b'] :: (GHC.Exts.IsList l, GHC.Exts.Item l ~ Char) => l\n
    Run Code Online (Sandbox Code Playgroud)\n
  6. \n
  7. 数据构造函数Nothing(如果您想将无效构造函数视为文字)

    \n
    > :t Nothing\nNothing :: Maybe a\n
    Run Code Online (Sandbox Code Playgroud)\n

    Nothing例如,可以是 、 等类型的Maybe IntMaybe Char

    \n
  8. \n
\n


Wil*_*sem 3

Num是一个类型类,它是一类型,这看起来有点类似于 Java/C#/...中的接口。作为Num类型类成员的类型需要实现一组特定的功能,就像在 Java 中一样实现接口的类型应该实现某些方法。Char另一方面,A是类型,而不是类型类。

如果您编写整数文字,它可以是该类型类成员的任何类型Num,因为该类型类有一个函数,fromInteger :: Num a => Integer -> a然后调用该函数将整数文字转换为该数字类型。

'a'如果您像另一方面一样编写 char 文字,那么唯一可以解析的类型是Char.

对于字符串文字,您可以使用OverloadedStrings扩展名,在这种情况下,字符串文字可以采用属于IsStringtypeclass成员的任何类型。