takeWhile tail recursive error

Hello folks

I am learning PureScript through “functional programming made easier” book.
I am in the point to implement takeWhile. I made my first try and it works

``````takeWhile :: forall a. (a -> Boolean) -> List a -> List a
takeWhile _ Nil = Nil
takeWhile f (x:xs) = if f x then x : takeWhile f xs else Nil
``````

I said myself "lets make it tail recursive like many times the author does

I tried this:

``````takeWhile :: forall a. (a -> Boolean) -> List a -> List a
takeWhile func = reverse  <<< go Nil func where
go returnList _ Nil = returnList
go returnList f' (x : xs) = if f' x then go (x : returnList) f' else returnList

``````

and the building says

``````Could not match type

List

with type

Function (List t1)

while trying to match type List t1
with type List t1 -> List t1
while checking that expression (compose reverse) ((go Nil) func)
where
go = \returnList ->
...
has type List a0 -> List a0
in value declaration takeWhile

where a0 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
t1 is an unknown type

``````

i cannot understand what the problem is since a little above on the excersizes i typed (and it worked )

``````take :: forall a. Int -> List a -> List a
take howMuch  = reverse <<< go Nil (max 0 howMuch) where
go takenList _ Nil  = takenList
go takenList 0 _ = takenList
go takenList howMuch' (x:xs) = go (x : takenList) (howMuch' - 1) xs

``````

has something with the predicator has to do ? I feel a little lost, any help would be nice.

1 Like

Welcome @patourasalexandros!
Sometimes spotting those errors can be a real challenge. I couldn’t spot the issue with your implementation just by looking it over.
The trick when you’re getting an error like this that’s not giving you enough helpful information is to try adding more annotations to point the compiler in the right direction. For example here, you could try annotating `go` which helps IMO. Try figuring out the type of `go` yourself and adding that annotation and see if the resulting error message gives you enough info to get unstuck. Post here again if you’re still stuck!

1 Like

Take a closer look at this line:

``````go returnList f' (x : xs) = if f' x then go (x : returnList) f' else returnList
``````

The right-hand side is an `if`; both branches of the `if` need to have the same type. The false branch of the `if` has type `List a`. In the true branch, you’re applying `go` to two arguments; what is the type of that expression?

1 Like

When you come across errors like this…

… it usually means you didn’t provide a function with all of its arguments.

1 Like

i did not know that if has to have the same signatures in both branches . thanks