Skip to content

Instantly share code, notes, and snippets.

@chrisdone-artificial
Last active November 19, 2024 15:36
Show Gist options
  • Save chrisdone-artificial/d4d299b50cafa64e90388be6de49f44e to your computer and use it in GitHub Desktop.
Save chrisdone-artificial/d4d299b50cafa64e90388be6de49f44e to your computer and use it in GitHub Desktop.
variants - total matching
type A = Variant (ConsL "Age" Int (ConsL "Name" Text NilL))
demo :: A
demo = LeftV 1
demo' :: A
demo' = RightV (LeftV "x")
match :: String
match = runAccessor demo $ ConsA show $ ConsA Text.unpack NilA
--------------------------------------------------------------------------------
-- Variants
-- | A variant; one of the given choices.
data Variant xs where
LeftV :: forall k a xs. a -> Variant (ConsL k a xs)
RightV :: forall k a xs k'' a''. Variant (ConsL k'' a'' xs) -> Variant (ConsL k a (ConsL k'' a'' xs))
-- | Accessor of a given variant. A record whose fields all correspond
-- to the constructors of a sum type, and whose types are all `a ->
-- r` instead of `a`.
data Accessor (xs :: List) r where
NilA :: Accessor 'NilL r
ConsA :: forall k a r xs. (a -> r) -> Accessor xs r -> Accessor (ConsL k a xs) r
-- | Run a total case-analysis against a variant, given an accessor
-- record.
runAccessor :: Variant xs -> Accessor xs r -> r
runAccessor (LeftV a) (ConsA f _) = f a
runAccessor (RightV xs) (ConsA _ ys) = runAccessor xs ys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment