
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

On Sun, Sep 15, 2019 at 5:28 PM Hilco Wijbenga
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.

You can also define a default type family instance to the class declaration:
class HasToList collection where
type Requirement collection element :: Constraint
type Requirement collection element = ()
Regards,
Erik
On Mon, 16 Sep 2019 at 04:02, Hilco Wijbenga
On Sun, Sep 15, 2019 at 5:28 PM Hilco Wijbenga
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. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (2)
-
Erik Hesselink
-
Hilco Wijbenga