为什么不'尾x:头x'工作?

Ste*_*ski 1 haskell

Haskell新手.为什么下面的代码工作?我如何连接这样的尾部和头部?

func :: [String] -> [String]
func x = tail x:head x
Run Code Online (Sandbox Code Playgroud)

Tho*_*son 7

让我们通过这些类型来理解为什么在我们专注于正确的解决方案之前这不起作用.

你提出:

func :: [String] -> [String]
func x = tail x:head x
Run Code Online (Sandbox Code Playgroud)

我们知道:

tail x :: [String]
head x :: String
(:)    :: String -> [String] -> [String]
            ^          ^ the 'head' argument's position
            ^---the 'tail' argument's position
Run Code Online (Sandbox Code Playgroud)

很明显,类型不匹配 - 一个预期元素的列表和一个预期列表的元素.

值得注意的是,没有任何默认snoc运算符,它是列表末尾的元素.您可以做的是通过列表附加到列表(++) :: [String] -> [String] -> [String].既然head xs不是,[String]我们可以通过方括号来制作它:[head xs].

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

func (firstElement : restOfList) = restOfList ++ [firstElement]
Run Code Online (Sandbox Code Playgroud)

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

func [] = []
Run Code Online (Sandbox Code Playgroud)