
6 Sep
2018
6 Sep
'18
4:18 a.m.
On Wed, Sep 05, 2018 at 11:37:07AM -0400, Ben Doyle wrote:
{-#LANGUAGE GADTs#-}
data Enumerator a b where Enumerator :: a -> a -> Enumerator a a
instance Enum a => Foldable (Enumerator a) where foldMap f (Enumerator x y) | fromEnum x > fromEnum y = mempty | otherwise = f x <> foldMap f (Enumerator (succ x) y)
Here we're using a GADT to express that our two-parameter Enumerator type in practice always has a == b (at the type level). Which lets us constrain the values inside our new Foldable structure, while still having a type of kind (* -> *) like the the typeclass requires.
This is ingenious!