2013-04-03 30 views
2

我正在閱讀了解Haskell以及第40頁 - as-patterns。Haskell [x]和x表示法 - 作爲模式示例

我已經改變了例子略是:

firstLetter :: String -> String 
firstLetter "" = "Empty string, oops" 
firstLetter [email protected](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 [email protected](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必須是類型列表?

回答

6

++是串聯列表:

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

[x]是一個列表,x是不是列表。

firstLetter (x:xs)是模式匹配的一個例子。

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

該操作符在列表之前添加元素。
因此x的類型是元素和類型xs是元素的列表。 Haskell在列表中添加後綴's'是很常見的。

+0

啊這是打印不起作用的原因。 –

+0

是的,你試圖連接列表和元素,而不是兩個列表。 – Vladimir

5

String定義爲type String = [Char]

"Qwerty"['Q', 'w', 'e', 'r', 't', 'y']的簡寫;這又是'Q' : 'w' : 'e' : 'r' : 't' : 'y' : []的簡寫。

因此,當您將x : xs"Qwerty"匹配時,您會得到x = 'Q'xs = "werty"

x  : xs 
('Q') : ('w' : 'e' : 'r' : 't' : 'y' : []) 

注:x = 'Q',NOT x = "Q"'Q'Char"Q"String(即[Char])。但是,如果您有'Q'並且您想要"Q",則可以編寫['Q'],因爲"Q"只是['Q']的簡寫。

所以簡短的答案是,你必須這樣做才能使類型匹配。 [x]是長度爲1的列表,其單個元素是x


在此:

firstLetter [email protected](x:xs) 
    = "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs 

你建立使用++打印的字符串。有型號

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

++需要兩個列表,並給你一個列表。

但是x不是一個列表。所以你得到一個類型錯誤。

而是使用

"The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs 

現在所有的參數都++列表,以及所有的類型匹配起來。

但是你可以改用

"The first letter of " ++ all ++ " is " ++ x : " otherbit " ++ xs 

因爲:類型由

(:) :: a -> [a] -> [a] 
+0

非常明確的解釋,謝謝。 –

+0

所以在我的情況下使用x,x ='Q' - 但爲什麼不打印Char Q?由於弗拉基米爾++評論? –

3

[X]表示 「只包含元素x的列表」 中給出。

作爲Haskell中的字符串是一個字符列表,如果x是字符'Q',那麼[x]是字符串「Q」。 ++運算符期望接收兩個字符串作爲參數,所以你不能只給它一個字符。

這就是編譯器告訴你的:Couldn't match expected type `[Char]' with actual type `Char'意味着編譯器需要一個類型爲[Char]的參數(它是一個字符列表,與String相同),但是您將它傳遞給一個Char。

1

還可以注意到,在許多編程語言中,連接運算符要麼被重載,以便根據兩邊的類型有多個實現,要麼將參數轉換爲字符串。這是而不是在Haskell的情況。

+0

是的,我在想那個。例如,在JavaScript +意味着添加,但也串聯。我認爲Haskell更僵化的方式更好。在編譯時比運行時更好地捕捉問題。 –

相關問題