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