Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell[x]和x表示法-作为模式示例_List_Haskell - Fatal编程技术网

List Haskell[x]和x表示法-作为模式示例

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

我正在阅读《从哈斯克尔身上学到好东西》和第40页的《作为模式》

我将示例稍微更改为:

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]