-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subtrees with existentially quantified types #7
Comments
To resolve the cliff-hanger... |
pull request #8 contains a small example, here is a more elaborate one: {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
data Hidden = forall t ts . Type Fam t => Hide t (Fam t ts)
data Fam ft ts where
Hidden' :: Fam t ts -> Fam Hidden ts
False' :: Fam Bool Nil
True' :: Fam Bool Nil
instance Family Fam where
False' `decEq` False' = Just (Refl, Refl)
True' `decEq` True' = Just (Refl, Refl)
Hidden' l `decEq` Hidden' r = do (Refl, Refl) <- l `decEq` r; Just (Refl, Refl)
_ `decEq` _ = Nothing
fields False' False = Just CNil
fields True' True = Just CNil
fields (Hidden' fam) (Hide a fam') = do (Refl, Refl) <- fam `decEq` fam'; fields fam a
fields _ _ = Nothing
string False' = "F"
string True' = "T"
string (Hidden' a) = "[" ++ string a ++ "]"
instance Type Fam Hidden where
constructors = [Meta $ \(Hide (a :: t) _) -> head $ [ Concr (Hidden' con)
| Concr con :: Con Fam t <- constructors
, Just _ <- [fields con a]
]
]
instance Type Fam Bool where
constructors = [Concr False', Concr True']
hDiff :: Hidden -> Hidden -> EditScript Fam Hidden Hidden
hDiff = diff Here the result: I am cheating a little bit by embedding a family member in the |
Okay, for posterity, here is the complete code with the trick mentioned in my previous comment: {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
data Hidden = forall t ts . Type Fam t => Hide t
data Fam ft ts where
Hidden' :: Fam t ts -> Fam Hidden ts
False' :: Fam Bool Nil
True' :: Fam Bool Nil
instance Family Fam where
False' `decEq` False' = Just (Refl, Refl)
True' `decEq` True' = Just (Refl, Refl)
Hidden' l `decEq` Hidden' r = do (Refl, Refl) <- l `decEq` r; Just (Refl, Refl)
_ `decEq` _ = Nothing
fields False' False = Just CNil
fields True' True = Just CNil
fields (Hidden' fam) (Hide (a :: t)) = head [ fields fam a
| Concr fam' :: Con Fam t <- constructors
, Just (Refl, Refl) <- [fam `decEq` fam']
]
fields _ _ = Nothing
string False' = "F"
string True' = "T"
string (Hidden' a) = "[" ++ string a ++ "]"
instance Type Fam Hidden where
constructors = [Meta $ \(Hide (a :: t)) -> head $ [ Concr (Hidden' con)
| Concr con :: Con Fam t <- constructors
, Just _ <- [fields con a]
]
]
instance Type Fam Bool where
constructors = [Concr False', Concr True']
hDiff :: Hidden -> Hidden -> EditScript Fam Hidden Hidden
hDiff = diff *Data.Generic.Diff> Hide True *Data.Generic.Diff> Hide True |
Neither the
Concr
nor theAbstr
ways of describing the subtrees of a value allow existentially typed subtrees. I have come up with a new way, but I would like to know how others have tackled this problem. I'd gladly follow up with a pull request (a 2-liner) if there is no known good practice for this.The text was updated successfully, but these errors were encountered: