为什么 “Anna” ++ [‘ ‘] 在 Haskell 中可以工作,但 1 ++ [‘ ‘] 不行?

huangapple go评论50阅读模式
英文:

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

问题

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

我尝试过:
"Anna" ++ [' '] 起作用,
1 ++ [' '] 不起作用。
原因是什么?

英文:

I was trying to build a list of strings, but i don't get why String ++ [' '] works.
If i try to do with numbers, for example, 1 ++ [' '], it doesn't work .

I did :
"Anna" ++ [' '] WORKS
but 1 ++ [' '] NOT.
What is the reason?

答案1

得分: 6

在GHCi中,您可以使用:info命令来获取有关名称定义的信息。 (此外,我已将我的提示设置为lambda,通过将:set prompt "λ "添加到我的.ghci配置文件中。)

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

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

λ :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

1 ++ [' '] 不起作用,因为它要求 1 具有类型 [Char]。数字字面值通过 Num 类型类进行重载,因此编译器会寻找 instance 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 ++ [' ']

虽然从技术上讲,可以定义这样的实例,或者实际上是适用于任何 Applicative 的通用实例,但它没有包含在标准库中,因为它很容易无意中使用;如果遵循 Num 的规则,那么对于 String 来说,它的行为可能会令人惊讶。

英文:

In GHCi you can use the :info command to get information about how a name is defined. (Aside, I have set my prompt to a lambda by adding :set prompt &quot;λ &quot; to my .ghci config file.)

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

String is a type synonym for [Char], a list of Unicode characters. Single quotation marks indicate a character, and of course you can make a list of them.

λ :type &#39; &#39;
&#39; &#39; :: Char

λ :type [&#39; &#39;]
[&#39; &#39;] :: [Char]

And double quotation marks form a String.

λ :type &quot; &quot;
&quot; &quot; :: String

Since the two types are equal, there are multiple ways of expressing equivalent values.

λ &quot; &quot; == [&#39; &#39;]
True

λ &quot;abc&quot; == [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]
True

λ &quot;abc&quot; == &#39;a&#39; : &quot;bc&quot;
True

λ &quot;abc&quot; == &#39;a&#39; : &#39;b&#39; : &#39;c&#39; : []
True

And since String is a list, you can use list operations on it.

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

λ (&quot;abc&quot; ++ &quot;def&quot;) == ([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;] ++ [&#39;d&#39;, &#39;e&#39;, &#39;f&#39;])
True

Whereas, 1 ++ [&#39; &#39;] doesn’t work because it requires 1 to have the type [Char]. Number literals are overloaded via the Num typeclass, so this means that the compiler looks for instance Num [Char]. Since that instance isn’t defined, this raises an error.

λ :type 1 ++ [&#39; &#39;]

&lt;interactive&gt;:1:1: error:
    • No instance for (Num [Char]) arising from the literal ‘1’
    • In the first argument of ‘(++)’, namely ‘1’
      In the expression: 1 ++ [&#39; &#39;]

While it is technically possible to define such an instance—or in fact a general instance for any Applicative—it’s not included in the standard library because it would be easy to use unintentionally; and if it followed the laws for Num, then it would behave in a potentially surprising way for String.

答案2

得分: 4

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

(++) :: [a] -> [a] -> [a]
         ^      ^
         |      |
    第一个列表  |
                |
            第二个列表

因为 1 不是一个列表,所以 ++ 运算符不能用于它。

英文:

The reason is that the ++ operator's definition says that it has two arguments, both lists:

(++) :: [a] -&gt; [a] -&gt; [a]
         ^      ^
         |      |
    first list  |
                |
            second list

Since 1 is not a list, ++ operator doesn't work on it.

huangapple
  • 本文由 发表于 2023年5月24日 23:37:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定