Skip to content

Instantly share code, notes, and snippets.

@DanielSchuessler
Created July 23, 2011 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielSchuessler/1100723 to your computer and use it in GitHub Desktop.
Save DanielSchuessler/1100723 to your computer and use it in GitHub Desktop.
Subset variants
{-# LANGUAGE ScopedTypeVariables, GADTs, KindSignatures, MultiParamTypeClasses, FlexibleContexts #-}
data A
data B
data C
data SumABC :: (* -> *) where
A :: Int -> SumABC A
B :: Int -> SumABC B
C :: SumABC C
class Elem t set where
elemPrf :: set t
-- | Represents the set {A,B}
data AB :: (* -> *) where
AB_A :: AB A
AB_B :: AB B
instance Elem A AB where elemPrf = AB_A
instance Elem B AB where elemPrf = AB_B
unAB :: forall t. Elem t AB => SumABC t -> Int
unAB x = case elemPrf :: AB t of
AB_A -> case x of
A i -> i
AB_B -> case x of
B i -> i
-- Alternative without scoped type variables
-- | Type inference helper
elemPrf' :: Elem t set => f t -> set t
elemPrf' = const elemPrf
-- Same type as unAB
unAB' x = case elemPrf' x of
AB_A -> case x of
A i -> i
AB_B -> case x of
B i -> i
main = print (unAB' (A 1), unAB' (B 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment