[Haskell-cafe] Default "type" in type class

Hilco Wijbenga hilco.wijbenga at gmail.com
Mon Sep 16 02:00:50 UTC 2019


On Sun, Sep 15, 2019 at 5:28 PM Hilco Wijbenga <hilco.wijbenga at gmail.com> wrote:
>
> Hi all,
>
> I'm trying to create a "HasToList" type class. It starts off really simple:
>
> class HasToList collection where
>         toList ∷ collection element → [element]
>
> instance HasToList Set where
>         toList = Data.Set.toList
>
> Unfortunately, this breaks down with Data.EnumSet.EnumSet. So
>
> instance HasToList EnumSet where
>         toList = Data.EnumSet.toList
>
> doesn't compile and I could not find a way to add "Enum a =>" to
> either the instance or "toList". (Well, not without making the
> compiler upset.)
>
> With the aid of ConstraintKinds and TypeFamilies (and not much
> understanding on my end, obviously) I created
>
> class HasToList collection where
>         type Requirement collection element :: Constraint
>         toList ∷ Requirement collection element => collection element
> → [element]
>
> instance HasToList Set where
>         type Requirement Set a = ()
>         toList = Data.Set.toList
>
> instance HasToList EnumSet where
>         type Requirement EnumSet a = Enum a
>         toList = Data.EnumSet.toList
>
> This works but now I have to add the constraint to every instance even
> though only a tiny minority actually need it. Is there a way to add a
> default "type implementation"?
>
> I tried the obvious
>
> type Requirement collection element :: Constraint = ()
>
> and
>
> type Requirement collection element :: Constraint
> type Requirement collection element :: Constraint = ()
>
> but neither compiles.
>
> Another problem is that the compiler can't compile something like this:
>
> isteps ∷ HasToList collection ⇒ collection String → [(Int, String)]
> isteps steps = Data.List.Index.indexed (toList steps)
>
> because it doesn't know which constraint to apply ("Could not deduce:
> Requirement hasToList String"). That seems fair but also irrelevant at
> this point.
>
> I feel like this is all far too complicated for what I'm trying to
> accomplish. :-) While I would like to have an answer to the questions
> above, I guess what I really want is a simpler way to implement
> HasToList.
>
> Cheers,
> Hilco

This:

class HasToList collection element where
        toList ∷ collection element -> [element]

instance HasToList Set element where
        toList = Data.Set.toList

instance Enum element => HasToList EnumSet where
        toList = Data.EnumSet.toList

compiles fine, of course.

Strange, I thought I had tried that.


More information about the Haskell-Cafe mailing list