When dealing with type families, it is often handy to use equality constraints to avoid having to repeat some type-function's name in a signature:
class Foo f where
type BulkyAssociatedType f :: *
foo :: BulkyAssociatedType f -> f
...
bar :: forall m f b .
( Monad m, Foo f, b ~ BulkyAssociatedType f
, Monoid b, Monoid (m b)
) => f -> m f
This works even if the abbreviation doesn't turn up in the signature itself, only in the constraints.
With classes, this is apparently not possible;
class ( Foo f, b ~ BulkyAssociatedType f, Monoid b, ...) => Bar f
complains about type variable b
not being in scope.
Is the some way to achieve a similar thing, to avoid a bit of repetition-boilerplate?
It surprised me to learn you can't do that (I've used the same technique and know it works in instance declarations), but there seems to be a long-standing GHC feature request to support this.
Maybe you can use ConstraintKinds
to get the same benefit:
{-# LANGUAGE TypeFamilies , FlexibleContexts , ConstraintKinds #-}
import Data.Monoid
class Foo f where
type BulkyAssociatedType f :: *
type B f = (Monoid (BulkyAssociatedType f))
class ( Foo f, B f) => Bar f
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With