Skip to content

Instantly share code, notes, and snippets.

@mankyKitty
Last active March 20, 2019 22:40
Show Gist options
  • Save mankyKitty/9ca2b431039e2b5e2f70f4dc700cf62b to your computer and use it in GitHub Desktop.
Save mankyKitty/9ca2b431039e2b5e2f70f4dc700cf62b to your computer and use it in GitHub Desktop.
generalised hedgehog command, so you don't have to keep rewriting `HTraversable` instances, maybe...
-- *sniff sniff* .. I smell, overkill
type family CmdArg (a :: k) :: Type
-- Totally overdone, but you can use promoted types for a bit of fun...
-- I don't use the promoted type here, but could be nice for flexibility later, maybe.
data Cmd (a :: k) (v :: Type -> Type) where
Cmd :: Show (CmdArg a) => CmdArg a -> Cmd a v
deriving instance Show (Cmd a v)
-- I guess you could also KISS with
newtype Cmd a (v :: Type -> Type) = Cmd a
deriving Show
-- Write this once, and just re-use 'Cmd' as the carrier for your different Command types.
instance HTraversable (Cmd a) where
htraverse _ (Cmd a) = pure (Cmd a)
-- Just have to write a type instance? worse? better? few chars == victory!! lulz
type instance CmdArg DrinkType = DrinkType
data DrinkType
= Coffee
| Tea
| EspressoMartini
deriving (Show, Eq, Enum, Bounded)
cSetDrinkType
:: forall g m. (MonadGen g, MonadTest m, MonadIO m)
=> C.Machine
-> Command g m Model
cSetDrinkType mach = Command gen exec
[ Update $ \_ (Cmd dt) _ -> Model dt
, Ensure $ \_ (Model dt) _ drink -> dt === drink
]
where
gen :: Model Symbolic -> Maybe (g (Cmd DrinkType Symbolic))
gen _ = pure $ Cmd <$> Gen.enumBounded
exec :: Cmd DrinkType Concrete -> m C.Drink
exec (Cmd d) = evalIO $ do
mach & case d of
Coffee -> C.coffeed
Tea -> C.tea
EspressoMartini -> C.espressoMartini
view C.drinkSetting <$> C.peek mach
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment