Using a Barbie type as a field in another Barbie type with Barbies-TH

98 Views Asked by At

I'd like to use Barbies-TH to create two Barbie records, where one is used as a field type in the other:

data Player = MkPlayer
  { playerLeft, playerRight, playerShoot, playerStart :: Bool
  } 

data Inputs = MkInputs
  { player1, player2 :: Player
  , dips :: BitVector 8
  , coin :: Bool
  } 

I can wrap the first one in declareBareB just fine:

import Barbies
import Barbies.Bare
import Barbies.TH

declareBareB [d|
  data Player = MkPlayer
    { playerLeft, playerRight, playerShoot, playerStart :: Bool
    } |]

However, because now the kind of Player is Type -> (Type -> Type) -> Type, I can't use it inside a declareBareB for Inputs, where the whole point is to pretend that there's no wrapper functor:

declareBareB [d|
  data Inputs = MkInputs
    { player1, player2 :: Player
    , dips :: BitVector 8
    , coin :: Bool
    } |]

This gives the, quite unsurprising, type error:

src/Hardware/SpaceInvaders/Input.hs:11:1: error:

     • Expecting two more arguments to ‘Player’
       Expected a type, but
       ‘Player’ has kind
       ‘Type -> (Type -> Type) -> Type’
     • In the third argument of ‘Wear’, namely ‘Player’
       In the type ‘(Wear sw_aRck h_aRcl Player)’
       In the definition of data constructor ‘MkInputs’
    |
 11 | declareBareB [d|
    | ^^^^^^^^^^^^^^^^...

What I'd like is to somehow propagate the clothes of Inputs to the Player, so that the type coming out of Barbies-TH would be

data Inputs cover f = MkInputs
    { player1, player2 :: Player cover f
    , dips :: Wear cover f (BitVector 8)
    , coin :: Wear cover f Bool
    }

(and NOT player1, player2 :: Wear cover f (Player Bare Identity))

0

There are 0 best solutions below