模式x:带字符串的xs

时间:2016-09-11 19:25:31

标签: haskell pattern-matching

我是Haskell世界的新手。我正在阅读在线http://learnyouahaskell.com,但我无法理解有关模式匹配部分的细节。我写了这些函数

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]

当我调用此函数时,它工作正常。我想知道为什么在其他情况下我需要括号。什么是第一封信。

2 个答案:

答案 0 :(得分:4)

"Hello ++ firstLetter

有类型:

[Char] ++ Char

如您所见,这是不可能的。您无法将Char添加到[Char],它们是不同的类型!

但是做了

[firstLetter]

您正在创建一个包含1个元素firstLetter的列表。由于firstLetterChar,您将获得Char的列表,即列表的类型为[Char]

允许添加2个相同类型的列表,这就是它在第二种情况下有效的原因。

答案 1 :(得分:4)

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

Prelude> :t (++)
(++) :: [a] -> [a] -> [a]

这意味着它需要两个作为参数的列表。

同样,让我们​​看看(:)做了什么:

Prelude> :t (:)
(:) :: a -> [a] -> [a]

所以(:)的第一个参数根本不需要是一个列表。如果我们修复a == Char,我们实际上会获得(:) :: Char -> String -> String

我们可以定义一个函数headStr(召回String == [Char]):

headStr :: String -> Char
headStr (x:_) = x
headStr _ = error "Empty string!"

请注意,由于(:) x :: Char的类型{。}}。

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

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

它不会进行类型检查,因为在非错误情况下我们得到[Char] ++ Char。正如ghci有用地告诉我们的那样,(++)的第二个参数必须始终是一个列表,在这种情况下,因为第一个参数是[Char],它也必须是[Char]

正如您自己注意到的那样,可以通过将x包装在列表中来解决此问题:

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

这可以按预期工作。

相关问题