The t
in the signature
where step :: Bool -> t -> Bool
is not the same t
as that occurring in the signature of any'
. Instead, it is interpreted as a fresh type variable which is local to the step
signature.
In other words, your code is actually equivalent to
any' :: (t -> Bool) -> [t] -> Bool
any' f = foldl' step False
where step :: Bool -> a -> Bool -- t renamed to a
step b x | f x = True
| otherwise = b
and the compiler then complains because step
claims in its signature to be applicable to any type a
while f requires a t
.
A possible fix is removing the step
signature. In this case the compiler will infer the right type on its own. This is not entirely pleasant from the programmer's point of view, since the compiler now will not check that the step
signature really is the one which the programmer intended.
Another fix, as suggested in the comments, is to enable a Haskell extension which allows us to write our type.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.List
any' :: forall t. (t -> Bool) -> [t] -> Bool
any' f = foldl' step False
where step :: Bool -> t -> Bool
step b x | f x = True
| otherwise = b
Here the explicit quantifier forall t
tells the compiler that the t
occurring inside the definition of any'
is really the same t
, and not a fresh type variable.