Haskell 模式x:xs和字符串

Haskell 模式x:xs和字符串,haskell,pattern-matching,Haskell,Pattern Matching,我在哈斯克尔的世界里是个新手。我正在网上阅读这篇文章,但我无法理解关于模式匹配部分的一个小细节。我已经编写了这些函数 myFunc' (firstLetter:_) = firstLetter -- returns firstLetter of given string 但是如果我这样做的话 myFunc' (firstLetter:_) = "Hello" ++firstLetter 调用此函数时给出以下错误 Couldn't match type ‘Char’ with ‘[Char]’

我在哈斯克尔的世界里是个新手。我正在网上阅读这篇文章,但我无法理解关于模式匹配部分的一个小细节。我已经编写了这些函数

myFunc' (firstLetter:_) = firstLetter -- returns firstLetter of given string
但是如果我这样做的话

myFunc' (firstLetter:_) = "Hello" ++firstLetter
调用此函数时给出以下错误

Couldn't match type ‘Char’ with ‘[Char]’
      Expected type: [[Char]]
        Actual type: [Char]
但是如果我像这样修改函数

myFunc' (firstLetter:_) = "Hello" ++ [firstLetter]
当我调用这个函数时,它工作得很好。我想知道为什么在其他情况下我需要括号。实际上什么是第一个字母

"Hello ++ firstLetter
这些类型有:

[Char] ++ Char
正如你所见,这是不可能的。您不能将字符添加到[Char],它们是不同的类型

但是通过这样做

[firstLetter]
您正在创建一个包含1个元素firstLetter的列表。因为firstLetter是Char,所以您将得到一个Char列表,即列表的类型为[Char]

允许添加两个相同类型的列表,这就是为什么它在第二种情况下有效

这些类型有:

[Char] ++ Char
正如你所见,这是不可能的。您不能将字符添加到[Char],它们是不同的类型

但是通过这样做

[firstLetter]
您正在创建一个包含1个元素firstLetter的列表。因为firstLetter是Char,所以您将得到一个Char列表,即列表的类型为[Char]


允许添加两个相同类型的列表,这就是为什么它在第二种情况下有效。

首先,如果您在ghci中检查++的类型,您会得到:

Prelude> :t (++)
(++) :: [a] -> [a] -> [a]
这意味着它需要两个a的列表作为参数

同样,让我们看看:做什么:

所以:的第一个论点根本不需要是一个列表。如果我们修正a==Char,我们实际上会得到:::Char->String->String

我们可以定义一个函数headStr recall String==[Char]:

注意,由于:的类型,在本例中为x::Char

另一方面,如果我们试图定义:

hello :: String -> String
hello (x:_) = "Hello" ++ x
hello _ = error "Empty string!"
它不会键入check,因为在无错误的情况下,我们得到[Char]++Char。正如ghci告诉我们的,++的第二个参数必须始终是一个列表,在本例中,由于第一个参数是[Char],所以它也必须是[Char]

正如您自己所注意到的,这可以通过在列表中包装x来解决:

hello' :: String -> String
hello' (x:_) = "Hello" ++ [x]
hello' _ = error "Empty string!"

这与预期一样有效。

首先,如果您检查ghci中的++类型,您会得到:

Prelude> :t (++)
(++) :: [a] -> [a] -> [a]
这意味着它需要两个a的列表作为参数

同样,让我们看看:做什么:

所以:的第一个论点根本不需要是一个列表。如果我们修正a==Char,我们实际上会得到:::Char->String->String

我们可以定义一个函数headStr recall String==[Char]:

注意,由于:的类型,在本例中为x::Char

另一方面,如果我们试图定义:

hello :: String -> String
hello (x:_) = "Hello" ++ x
hello _ = error "Empty string!"
它不会键入check,因为在无错误的情况下,我们得到[Char]++Char。正如ghci告诉我们的,++的第二个参数必须始终是一个列表,在本例中,由于第一个参数是[Char],所以它也必须是[Char]

正如您自己所注意到的,这可以通过在列表中包装x来解决:

hello' :: String -> String
hello' (x:_) = "Hello" ++ [x]
hello' _ = error "Empty string!"

这一切都如期进行。

嗨,Rakete1111,谢谢你的评论。我刚刚做了另一个小实验来证实另一件事。您提到我不能在Char中添加[Char]。但是,当我在ghci'c':dfg中执行这一行时,它是有效的。所以我们可以说++运算符需要相同的类型。@CanEldem好的,从技术上讲,是的。您认为行是有效的,因为c的类型是dfg中元素的类型,即Char。c:dfg将无效。嗨,Rakete1111,谢谢你的评论。我刚刚做了另一个小实验来证实另一件事。您提到我不能在Char中添加[Char]。但是,当我在ghci'c':dfg中执行这一行时,它是有效的。所以我们可以说++运算符需要相同的类型。@CanEldem好的,从技术上讲,是的。您认为行是有效的,因为c的类型是dfg中元素的类型,即Char。c:dfg将是无效的。