barbies- Classes for working with types that can change clothes.

Safe HaskellNone




Sometimes one needs a type like Barbie Identity and it may feel like a second-class record type, where one needs to unpack values in each field. For those cases, we can leverage on closed type-families:

data Bare
data Covered

type family Wear t f a where
  Wear Bare    f a = a
  Wear Covered f a = f a

data SignUpForm t f
  = SignUpForm'
      { username  :: Wear t f String,
      , password  :: Wear t f String
      , mailingOk :: Wear t f Bool
 instance FunctorB (SignUpForm Covered)
 instance TraversableB (SignUpForm Covered)
 instance BareB SignUpForm

type SignUpRaw  = SignUpForm Maybe
type SignUpData = SignUpForm Bare

formData = SignUpForm "jbond" "shaken007" False :: SignUpData

Bare values

type family Wear t f a where ... Source #

The Wear type-function allows one to define a Barbie-type as

data B t f
  = B { f1 :: Wear t f Int
      , f2 :: Wear t f Bool

This gives rise to two rather different types:

  • B Covered f is a normal Barbie-type, in the sense that f1 :: B Covered f -> f Int, etc.
  • B Bare f, on the other hand, is a normal record with no functor around the type:
B { f1 :: 5, f2 = True } :: B Bare f


Wear Bare f a = a 
Wear Covered f a = f a 
Wear t _ _ = TypeError ((Text "`Wear` should only be used with " :<>: Text "`Bare` or `Covered`.") :$$: (((Text "`" :<>: ShowType t) :<>: Text "`") :<>: Text " is not allowed in this context.")) 

Covering and stripping

class FunctorB (b Covered) => BareB b where Source #

Class of Barbie-types defined using Wear and can therefore have Bare versions. Must satisfy:

bcover . bstrip = id
bstrip . bcover = id

Minimal complete definition


bstripFrom :: BareB b => (forall a. f a -> a) -> b Covered f -> b Bare Identity Source #

Generalization of bstrip to arbitrary functors

bcoverWith :: BareB b => (forall a. a -> f a) -> b Bare Identity -> b Covered f Source #

Generalization of bcover to arbitrary functors