[Haskell] Swapping parameters and type classes

Bas van Dijk v.dijk.bas at gmail.com
Mon Sep 17 15:17:14 EDT 2007


On 9/17/07, Mads Lindstrøm <mads_lindstroem at yahoo.dk> wrote:
> Hi Bas
>
> Thank you for the answer.
>
> I tried to "fill in some blanks" in the example you gave. And mostly got
> a lot of context reduction stack overflows :(
>
> Here is my example (a little closer to what I actually need):
>
> data Foo a b = Foo { first :: a, second :: b }
>
> class Bar (x :: * -> *) where
>     foo :: x a -> a
>
> instance Bar (Foo a) where
>     foo x = second x
>
> type family BarB a b :: * -> *
> type instance BarB a b = Foo b
>
> instance Bar (BarB a b) where
>     foo x = second x     -- this unexpectedly works!
> --  foo x = first x      -- This unexpectedly gives context reduction stack overflow
>
> What surprises me is that I still need to look at `second`, even though
> I use BarB. I thought I was swapping the parameters. Whats more changing
> the line:
>
> type instance BarB a b = Foo b
>
> to
>
> type instance BarB a b = Foo a  -- the last letter changed
>
> has no effect.
>
>
> Greetings,
>
> Mads Lindstrøm
>
> P.s. Why can we not just have the option of being explicit about which type parameters are applied? Something like:
>
> "instance Bar (apply a. Foo a b)" which would apply a and be identical to "instance Bar (Foo a)"
> "instance Bar (apply b. Foo a b)" which would apply b and be what I am trying to achieve.
>
> It would seem a lot more natural to me. But maybe there are other reasons why type families are a better solution?
>
> I do not know if I use the right terminology when saying "apply". Please correct if there is more correct terms.
>
>
> Bas van Dijk:
> > On 9/16/07, Mads Lindstrøm <mads_lindstroem at yahoo.dk> wrote:
> > > But what if I want to "apply" the 'b' ? How do I do that ?
> >
> > The following uses type families (functions) and compiles under GHC HEAD:
> >
> > {-# OPTIONS_GHC -XTypeFamilies -XEmptyDataDecls -XTypeSynonymInstances #-}
> >
> > data Foo a b
> >
> > class Bar (x :: * -> *)
> >
> > instance Bar (Foo a)
> >
> > type family BarB a b :: * -> *
> > type instance BarB a b = Foo b
> >
> > instance Bar (BarB a b)
> >
> >
> > regards,
> >
> > Bas van Dijk
>
>

Mads, my sollution was not correct.

This is why:

instance Bar (BarB a b)

is equal to:

instance Bar (Foo b)

which is just equal to:

instance Bar (Foo a)

The 'b' in  'instance Bar (Foo b)' has nothing to do with the 'b' in
'Foo a b'. In fact the 'b' in 'BarB a b' is equal to the 'a' in 'Foo a
b'.

Sorry that I bothered you with this but like I said, it was late and I
already consumed some wine. Not a good combination when programming
;-)

Bas.


More information about the Haskell mailing list