Reputation: 321
New to Haskell. Why does the following code not work? How do I concatenate the tail and the head like this?
func :: [String] -> [String]
func x = tail x:head x
Upvotes: 1
Views: 277
Reputation: 64740
Lets work through the types to understand why this didn't work before we focus on the proper solution.
You presented:
func :: [String] -> [String]
func x = tail x:head x
We know:
tail x :: [String]
head x :: String
(:) :: String -> [String] -> [String]
^ ^ the 'head' argument's position
^---the 'tail' argument's position
So clearly the types aren't matching up - a list where an element is expected and an element where a list is expected.
It's worth noting that there isn't any default snoc
operator, which cons's an element to the end of a list. What you can do is append to lists via (++) :: [String] -> [String] -> [String]
. Since the head xs
isn't a [String]
we could make it one via square brackets: [head xs]
.
More-over, the use of head
and tail
are not safe - they'll throw an exception if the list is empty. It is better to use pattern matching so the compiler can warn you about partial functions in addition to them being more visibly obvious. In this case we'd match the first element and the rest of the list:
func (firstElement : restOfList) = restOfList ++ [firstElement]
And looking at this it should be obvious func
isn't yet defined for empty lists so we can add one more case:
func [] = []
Upvotes: 7
Reputation: 321
Solution:
Change
func :: [String] -> [String]
func x = tail x:head x
to
func :: [String] -> [String]
func x = tail x++[head x]
Upvotes: 0