List Haskell[x]和x表示法-作为模式示例
我正在阅读《从哈斯克尔身上学到好东西》和第40页的《作为模式》 我将示例稍微更改为:List Haskell[x]和x表示法-作为模式示例,list,haskell,List,Haskell,我正在阅读《从哈斯克尔身上学到好东西》和第40页的《作为模式》 我将示例稍微更改为: firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs 然后可以这样使用: *Main> firstLetter "Qwerty
firstLetter :: String -> String
firstLetter "" = "Empty string, oops"
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs
然后可以这样使用:
*Main> firstLetter "Qwerty"
"The first letter of Qwerty is Q otherbit werty"
但是我对[x]和x之间的区别以及为什么在上面的示例中必须使用[x]感到困惑
例如,如果我改为
firstLetter :: String -> String
firstLetter "" = "Empty string, oops"
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs
我得到一个错误:
Couldn't match expected type `[Char]' with actual type `Char'
In the first argument of `(++)', namely `x'
In the second argument of `(++)', namely `x ++ " otherbit " ++ xs'
In the second argument of `(++)', namely
`" is " ++ x ++ " otherbit " ++ xs'
我可以使用xs
打印“werty”
,但必须使用[x]
打印“Q”。为什么呢
[x]
是什么意思
在(x:xs
)中,:
只对每个元素进行定界,因此x
是第一个元素。为什么不能使用x
打印
还有
xs
是什么类型的?价值清单?那么这是否意味着x
是一个元素,而xs
必须是list类型?String
被定义为类型String=[Char]
“Qwerty”
是['Q'、'w'、'e'、'r'、't'、'y']的缩写。
;这又是“Q”:“w”:“e”:“r”:“t”:“y”:[]
因此,当您将x:xs
与“Qwerty”
匹配时,您将得到x='Q'
和xs=“werty”
注意:x='Q'
,而不是x=“Q”
'Q'
是一个字符
,'Q'
是一个字符串
(即[Char]
)。但是如果你有'Q'
并且你想要“Q”
,你可以写['Q']
,因为“Q”
只是['Q']
的简写
因此,简单的回答是,你必须这样做,使类型匹配[x]
是长度为1的列表,其单个元素为x
在这方面:
firstLetter all@(x:xs)
= "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs
您正在使用++
构建要打印的字符串。那是典型的
(++) :: [a] -> [a] -> [a]
i、 e.++
获取两个列表,并返回一个列表
但是x
不是一个列表。所以你得到了一个类型错误
相反,你使用
"The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs
现在,++
的所有参数都是列表,所有类型都匹配
但是你可以用
"The first letter of " ++ all ++ " is " ++ x : " otherbit " ++ xs
因为:
的类型由
(:) :: a -> [a] -> [a]
[x] 表示“仅包含元素x的列表”
由于Haskell中的字符串是字符列表,如果x是字符“Q”,则[x]是字符串“Q”。
++运算符希望接收两个字符串作为参数,因此不能只给它一个字符
这就是编译器告诉您的:
无法将预期的类型“[Char]”与实际的类型“Char”匹配
意味着编译器预期的参数类型为[Char](这是一个字符列表,与字符串相同),但您正在传递它一个字符。++
用于连接列表:
(++) :: [a] -> [a] -> [a]
[x]
是一个列表,x
不是一个列表
firstLetter(x:xs)
是模式匹配的一个示例
(:) :: a -> [a] -> [a]
此运算符在列表之前添加元素。因此,
x
的类型是元素,xs
的类型是元素列表。
在Haskell中,向列表名称添加后缀“s”是很常见的。人们还可以注意到,在许多编程语言中,连接运算符要么重载,以便根据两侧的类型有多个实现,要么将参数转换为字符串。这不是Haskell的例子。所以在我的例子中使用x,x='Q'-但是为什么它不打印字符Q呢?因为Vladimir的++评论?是的,您尝试连接列表和元素,而不是两个列表。是的,我正在考虑这个问题。例如,在javascript+中表示添加,但也表示连接。我认为Haskell更严格的方式更好。在编译时捕获问题比在运行时捕获问题更好。
(:) :: a -> [a] -> [a]