2016-11-26 67 views
1

Haskell的新手。爲什麼下面的代碼不是工作?我該如何連接尾部和頭部?爲什麼'tail x:head x'不起作用?

func :: [String] -> [String] 
func x = tail x:head x 
+4

':'並不意味着「連接」。它具體採用單個元素(左側)和列表(右側)並生成新列表。 – melpomene

+0

@melpomene我明白了。那麼你如何建議我恰當地連接這個? –

+4

我建議像'func(x:xs)= xs ++ [x]''。請注意,'++'在左邊參數的長度上是線性的,所以你可能不想在循環中做這個。 – melpomene

回答

7

讓我們通過工種理解爲什麼我們專注於正確的在此之前沒有工作解。

您呈現:

func :: [String] -> [String] 
func x = tail x:head x 

我們知道:

tail x :: [String] 
head x :: String 
(:) :: String -> [String] -> [String] 
      ^  ^the 'head' argument's position 
      ^---the 'tail' argument's position 

所以很明顯的類型不匹配了 - 其中元素有望列表並在列表預計的元素。

值得注意的是,沒有任何默認的snoc運算符,哪個cons是元素到列表的末尾。你可以通過(++) :: [String] -> [String] -> [String]追加到列表中。由於head xs不是[String],我們可以通過方括號將其設爲一個:[head xs]

此外,使用headtail並不安全 - 如果列表爲空,它們將引發異常。最好使用模式匹配,這樣編譯器除了可以更明顯地看到部分函數外,還可以警告你。在這種情況下,我們會第一個元素和列表的其餘部分匹配:

func (firstElement : restOfList) = restOfList ++ [firstElement] 

而且看這應該是顯而易見的func還沒有空列表定義,因此我們可以添加更多的情況:

func [] = [] 
0

解決方案:

變化

func :: [String] -> [String] 
func x = tail x:head x 

func :: [String] -> [String] 
func x = tail x++[head x] 
+0

這將不起作用,因爲'tail x:[head x]'仍然是一個類型錯誤。 –

+0

@DietrichEpp編輯。 –

+2

你可能也想要一個空的列表大小寫,因爲似乎沒有必要讓這個函數在一個空列表上失敗。 – duplode