英文:
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 "λ "
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 ' '
' ' :: Char
λ :type [' ']
[' '] :: [Char]
And double quotation marks form a String
.
λ :type " "
" " :: String
Since the two types are equal, there are multiple ways of expressing equivalent values.
λ " " == [' ']
True
λ "abc" == ['a', 'b', 'c']
True
λ "abc" == 'a' : "bc"
True
λ "abc" == 'a' : 'b' : 'c' : []
True
And since String
is a list, you can use list operations on it.
λ :info ++
(++) :: forall a. [a] -> [a] -> [a] -- Defined in ‘GHC.Base’
infixr 5 ++
λ ("abc" ++ "def") == (['a', 'b', 'c'] ++ ['d', 'e', 'f'])
True
Whereas, 1 ++ [' ']
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 ++ [' ']
<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 ++ [' ']
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] -> [a] -> [a]
^ ^
| |
first list |
|
second list
Since 1
is not a list, ++
operator doesn't work on it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论