谁能解释为什么“Anna” ++ [' '] 在 Haskell 中有效,但不能在 1 ++ [' '] 中工作?

Can anyone explain why "Anna" ++ [' '] works in Haskell but not 1 ++ [' ']?

提问人:noentiendo 提问时间:5/24/2023 最后编辑:414owennoentiendo 更新时间:5/26/2023 访问量:101

问:

我试图建立一个字符串列表,但我不明白为什么 String ++ [' '] 有效。 如果我尝试使用数字,例如 1 ++ [' '],它不起作用。

我做了: “安娜” ++ [' '] 作品 但 1 ++ [' '] 不是。 原因是什么?

字符串 列表 Haskell 构建

评论

1赞 lsmor 5/24/2023
单引号 () 表示字符。双引号 () 用于字符串。在 haskell 中,a 是一个字符列表。因此与(注意双引号和单引号)相同。因此与这显然是类型错误相同'a' :: Char"hello" :: StringString[Char]"Anna" ++ [' ']"Anna" ++ " "1 ++ [' ']1 ++ " "
0赞 Daniel Wagner 5/26/2023
因为和有不同的类型...?"Anna"1

答:

4赞 Fyodor Soikin 5/24/2023 #1

原因是运算符的定义说它有两个参数,两个参数都列出:++

(++) :: [a] -> [a] -> [a]
         ^      ^
         |      |
    first list  |
                |
            second list

由于不是列表,因此运算符无法处理它。1++

6赞 Jon Purdy 5/25/2023 #2

在 GHCi 中,可以使用该命令获取有关如何定义名称的信息。(顺便说一句,我通过添加到我的配置文件中将提示设置为 lambda。:info:set prompt "λ ".ghci

λ :info String
type String :: Type
type String = [Char]
    -- Defined in ‘GHC.Base’

String是 的类型同义词,是 Unicode 字符的列表。单引号表示一个字符,当然你可以列出它们。[Char]

λ :type ' '
' ' :: Char

λ :type [' ']
[' '] :: [Char]

双引号形成 .String

λ :type " "
" " :: String

由于这两种类型相等,因此有多种方法可以表示等效值。

λ " " == [' ']
True

λ "abc" == ['a', 'b', 'c']
True

λ "abc" == 'a' : "bc"
True

λ "abc" == 'a' : 'b' : 'c' : []
True

由于是一个列表,您可以对它使用列表操作。String

λ :info ++
(++) :: forall a. [a] -> [a] -> [a]     -- Defined in ‘GHC.Base’
infixr 5 ++

λ ("abc" ++ "def") == (['a', 'b', 'c'] ++ ['d', 'e', 'f'])
True

然而,不起作用,因为它需要具有 .数字文本通过 typeclass 重载,因此这意味着编译器会查找 .由于未定义该实例,因此会引发错误。1 ++ [' ']1[Char]Numinstance Num [Char]

λ :type 1 ++ [' ']

<interactive>:1:1: error:
    • No instance for (Num [Char]) arising from the literal ‘1’
    • In the first argument of ‘(++)’, namely ‘1’
      In the expression: 1 ++ [' ']

虽然从技术上讲可以定义这样的实例(或者实际上是任何实例的通用实例),但它不包含在标准库中,因为它很容易无意中使用;如果它遵循 的定律,那么它的行为方式可能会令人惊讶。ApplicativeNumString