[Haskell-cafe] Multi-param typeclass as superclass of Single-param typeclasses
Baa
aquagnu at gmail.com
Fri Oct 27 07:39:50 UTC 2017
May be type families can help here? There was good article about
Pokemons and type families which seems to be close to such task IMHO...
> Welcome! You can certainly express the constraint you want. But you
> can't do what you're trying to do with ShapeBox.
>
> Let's take those two in reverse order. Before I start, though, an
> obligatory warning (with the assumption that you're new to Haskell,
> as well as this list): object orientation is usually not the best way
> to go in Haskell. I don't mean to shame you for the question; it's a
> good learning exercise. But in most practical cases plain old data
> and functions will serve you better than a bunch of ad-hoc
> typeclasses.
>
> So. We have an existential type, ShapeBox, that stores a Shape but
> hides what Shape it is. And it seems that you'd like to be able write
> something like:
>
> bar :: ShapeBox -> ShapeBox -> Bool
> bar (ShapeBox x) (ShapeBox y) = intersect x y
>
> The trouble is that the instance of intersect we call depends on the
> actual types of x and y, and we don't know those types (because we've
> hidden them on purpose). If x and y are both Circles we need to use
> the Intersect Circle Circle instance. If instead y is a Square we
> must use the Intersect Circle Square instance, which in principle
> could do something entirely different.
>
> But there's hope. The way to declare the constraint you're after is
> to put it on the instance declaration:
>
> instance (Shape a, Shape b) => Intersect a b where
> intersect x y = ...
>
> That says precisely that whenever a and b are shapes, you can
> intersect them. The catch is that you must write this instance using
> only the Shape-ness of x and y (which is all you know about them). So
> you won't be able to have one way to intersect squares and circles,
> and another for triangles and hexagons; you need to abstract all the
> knowledge that lets you intersect into the Shape class.
>
> The difference is between telling the compiler, "I promise I'll go and
> write a suitable instance for each pair of Shapes, really" (which
> Haskell won't allow), and saying "here's how to intersect any two
> shapes whatsoever."
>
> You may want to check out the diagrams package, which does something
> similar with the class HasEnvelope.
>
> Hope that helps,
>
> Ben
>
> On Thu, Oct 26, 2017 at 11:37 AM Tomasz Chronowski <
> chronowski.tomasz at gmail.com> wrote:
>
> > This is my first post here, so Hello everyone!
> >
> > In haskell it is possible to express a constraint "if 'a' and 'b'
> > are instance of 'AB' then 'a' is instance of 'A' and 'b' is
> > instance of 'B'":
> >
> > class (A a, B b) => AB a b ...
> >
> > Is it possible to express the converse - "if 'a' is instance of 'A'
> > and 'b' is instance of 'B' then 'a' and 'b' are instance of 'AB'"?
> >
> > I want to create a list of shapes that can be tested for
> > intersection. I think that possibility of expressing such
> > constraints would allow to doing this in a "Object Oriented" way:
> >
> > data Circle = Circle { ... }
> > data Square = Square { ... }
> >
> > class Shape a
> >
> > class Intersect a b where
> > intersect :: a -> b -> Bool
> >
> > -- pseudo haskell - "If 'a' is instance of 'Shape' and 'b' is
> > instance of 'Shape' then 'a' and 'b' are instance of 'Intersect'"
> > -- maybe some type hackery allows to express this?
> > constraint Shape a, Shape b => Intersect a b
> >
> > instance Shape Circle
> > instance Shape Square
> >
> > instance Intersect Circle Circle ...
> > instance Intersect Circle Square ...
> > ...
> >
> > data ShapeBox = forall a. Shape a => ShapeBox a
> >
> > foo = let x:y:_ = [ShapeBox Circle { ... }, ShapeBox Square
> > { ... }, ...] in intersect x y -- this should work because we know
> > for sure that there is an instance of Intersect for type of 'x' and
> > type of 'y'
> >
> > Is such idea already described somewhere?
> > _______________________________________________
> > 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.
More information about the Haskell-Cafe
mailing list