From af294c4cc162197a0a092c7d72d6fd3eef6c4cac Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Wed, 4 Mar 2015 16:33:37 +0100 Subject: [PATCH 1/2] final form of meta constructors - these don't need a bare List instance - can describe nodes whose subtrees have existential type --- src/Data/Generic/Diff.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Data/Generic/Diff.hs b/src/Data/Generic/Diff.hs index 28a6fec..c4345a1 100644 --- a/src/Data/Generic/Diff.hs +++ b/src/Data/Generic/Diff.hs @@ -219,6 +219,8 @@ class (Family f) => Type f t where data Con :: (* -> * -> *) -> * -> * where Concr :: (List f ts) => f t ts -> Con f t Abstr :: (List f ts) => (t -> f t ts) -> Con f t + --Retro :: (t -> (Dict (List f) ts, f t ts)) -> Con f t + Retro :: (t -> Con f t) -> Con f t class List f ts where list :: IsList f ts @@ -313,6 +315,8 @@ matchConstructor = tryEach constructors (forall ts. f t ts -> IsList f ts -> ts -> r) -> r tryEach (Concr c : cs) x k = matchOrRetry c cs x k tryEach (Abstr c : cs) x k = matchOrRetry (c x) cs x k + --tryEach (Retro c : cs) x k = case c x of (Dict, c) -> matchOrRetry c cs x k + tryEach (Retro c : cs) x k = tryEach (c x : cs) x k tryEach [] _ _ = error "Incorrect Family or Type instance." matchOrRetry :: (List f ts, Type f t) => f t ts -> [Con f t] -> t -> From f6c814cc43633f164768d0ec6f3f7ad79e9081f6 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Wed, 4 Mar 2015 16:42:09 +0100 Subject: [PATCH 2/2] rename Retro --> Meta - add some documentation - cleanups --- src/Data/Generic/Diff.hs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Data/Generic/Diff.hs b/src/Data/Generic/Diff.hs index c4345a1..23fec58 100644 --- a/src/Data/Generic/Diff.hs +++ b/src/Data/Generic/Diff.hs @@ -216,11 +216,13 @@ class (Family f) => Type f t where -- -- Use 'Abstr' for abstract constructors (e.g., for built-in types or types with many -- (or infinite) constructors) +-- +-- Use 'Meta' for abstract constructors whose subtrees are of existential type +-- (which means exposing 'ts' is forbidden by the type checker) data Con :: (* -> * -> *) -> * -> * where Concr :: (List f ts) => f t ts -> Con f t Abstr :: (List f ts) => (t -> f t ts) -> Con f t - --Retro :: (t -> (Dict (List f) ts, f t ts)) -> Con f t - Retro :: (t -> Con f t) -> Con f t + Meta :: (t -> Con f t) -> Con f t class List f ts where list :: IsList f ts @@ -315,8 +317,7 @@ matchConstructor = tryEach constructors (forall ts. f t ts -> IsList f ts -> ts -> r) -> r tryEach (Concr c : cs) x k = matchOrRetry c cs x k tryEach (Abstr c : cs) x k = matchOrRetry (c x) cs x k - --tryEach (Retro c : cs) x k = case c x of (Dict, c) -> matchOrRetry c cs x k - tryEach (Retro c : cs) x k = tryEach (c x : cs) x k + tryEach (Meta c : cs) x k = tryEach (c x : cs) x k tryEach [] _ _ = error "Incorrect Family or Type instance." matchOrRetry :: (List f ts, Type f t) => f t ts -> [Con f t] -> t ->