packages feed

partial-isomorphisms 0.1 → 0.2

raw patch · 3 files changed

+66/−15 lines, 3 files

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c)2010, University of Marburg
+Copyright (c)2010-11 University of Marburg
 
 All rights reserved.
 
partial-isomorphisms.cabal view
@@ -1,5 +1,5 @@ Name:                partial-isomorphisms
-Version:             0.1
+Version:             0.2
 Synopsis:            Partial isomorphisms.
 Description:         Partial isomorphisms as described in the 
                      paper:
src/Control/Isomorphism/Partial/TH.hs view
@@ -11,28 +11,77 @@  import Control.Isomorphism.Partial.Unsafe (Iso (Iso)) +-- | Extract the name of a constructor, e.g. ":" or "Just".+conName :: Con -> Name+conName (NormalC name fields)       =   name+conName (RecC name fields)          =   name+conName (InfixC lhs name rhs)       =   name+conName (ForallC vars context con)  =   conName con++-- | Extract the types of the constructor's fields.+conFields :: Con -> [Type]+conFields (NormalC name fields)       =   map (\(s, t) -> t) fields+conFields (RecC name fields)          =   map (\(n, s, t) -> t) fields+conFields (InfixC lhs name rhs)       =   map (\(s, t) -> t) [lhs, rhs]+conFields (ForallC vars context con)  =   conFields con++-- | Extract the constructors of a type declaration+decConstructors :: Dec -> Q [Con]+decConstructors (DataD _ _ _ cs _)    =  return cs+decConstructors (NewtypeD _ _ _ c _)  =  return [c]+decConstructors _                      +  = fail "partial isomorphisms can only be derived for constructors of data type or newtype declarations."++-- | Construct a partial isomorphism expression for a constructor, +-- given the constructor's name.+constructorIso :: Name -> ExpQ constructorIso c = do-  DataConI n _ d _             <-  reify c-  TyConI ((DataD _ _ _ cs _))  <-  reify d-  let Just con = find (\(NormalC n' _) -> n == n') cs+  DataConI n _ d _  <-  reify c+  TyConI dec        <-  reify d+  cs                <-  decConstructors dec+  let Just con      =   find (\c -> n == conName c) cs   isoFromCon (wildcard cs) con +wildcard :: [Con] -> [MatchQ] wildcard cs    =  if length cs > 1      then  [match (wildP) (normalB [| Nothing |]) []]      else  []-  ++-- | Converts a constructor name (starting with an upper-case+--   letter) into a function name (starting with a lower-case+--   letter).+rename :: Name -> Name+rename n +  = mkName (toLower c : cs) where c : cs = nameBase n++-- | Construct partial isomorphism definitions for all +--   constructors of a datatype, given the datatype's name.+--   The names of the partial isomorphisms are constructed by+--   spelling the constructor names with an initial lower-case+--   letter.+defineIsomorphisms :: Name -> Q [Dec] defineIsomorphisms d = do-  TyConI (DataD _ _ _ cs _) <- reify d-  let rename n -        = mkName (toLower c : cs) where c : cs = nameBase n-      defFromCon con@(NormalC n _) -        =  funD (rename n) -             [clause [] (normalB (isoFromCon (wildcard cs) con)) []]-  -  mapM defFromCon cs+  TyConI dec  <-  reify d+  cs          <-  decConstructors dec+  mapM (defFromCon (wildcard cs)) cs -isoFromCon wildcard (NormalC c fs) = do+-- | Constructs a partial isomorphism definition for a+--   constructor, given information about the constructor.+--   The name of the partial isomorphisms is constructed by+--   spelling the constructor name with an initial lower-case+--   letter.+defFromCon :: [MatchQ] -> Con -> DecQ+defFromCon wildcard con+  = funD (rename (conName con)) +      [clause [] (normalB (isoFromCon wildcard con)) []]++-- | Constructs a partial isomorphism expression for a+--   constructor, given information about the constructor.+isoFromCon :: [MatchQ] -> Con -> ExpQ+isoFromCon wildcard con = do+  let c     =   conName con+  let fs    =   conFields con   let n     =   length fs   (ps, vs)  <-  genPE n   v         <-  newName "x"@@ -44,6 +93,8 @@                         (normalB [| Just $(nested tupE vs) |]) []                     ] ++ wildcard)   [| Iso $f $g |]++  genPE n = do   ids <- replicateM n (newName "x")