为什么没有'尾x:头x'工作?

时间:2016-11-26 23:27:06

标签: haskell

Haskell新手。为什么以下代码有效?我如何连接这样的尾部和头部?

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

2 个答案:

答案 0 :(得分: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运算符,它是列表末尾的元素。您可以做的是通过(++) :: [String] -> [String] -> [String]附加到列表。由于head xs不是[String],我们可以通过方括号将其设为[head xs]

此外,使用headtail并不安全 - 如果列表为空,它们将抛出异常。最好使用模式匹配,以便编译器可以向您发出关于部分函数的警告,此外它们更明显。在这种情况下,我们匹配第一个元素和列表的其余部分:

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

考虑到这一点,显然func还没有为空列表定义,所以我们可以添加一个案例:

func [] = []

答案 1 :(得分:0)

解决方案:

更改

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

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