on master help sign in
Record projection

Given a record, defined as follows, for example: record Foo : Nat -> Set where MkFoo : (name : String) -> (things : Vect a n) -> Foo n Functions 'name' and 'things' are generated to extract the record fields. 'implicit_n' and 'implicit_a' are generated to extract the implicit parts.

commit3c42704162a97c7fae15db72ba439d5405267362 authorEdwin Brady <eb@cs.st-andrews.ac.uk> dateFri 27 Jan 2012, 11:46 (15 years ago) parent34331d9
4 files changed+71−5
CHANGELOG+9−1 src/Idris/ElabDecls.hs+54 src/Idris/ElabTerm.hs+3−3 src/Idris/Parser.hs+5−1
CHANGELOG+9−1
@@ -1,8 +1,16 @@
11New in 0.9.1:
2+-------------
3+
4+User visible changes:
25
36* dsl notation
4−* faster compilation (only compiling names which are used)
7+* record projection
58* auto implicits and default argument values {auto n : T}, {default val n : T}
9+* Additions to prelude
10+
11+Internal changes:
12+
13+* faster compilation (only compiling names which are used)
614
7150.1.x to 0.9.0:
816
src/Idris/ElabDecls.hs+54
@@ -88,6 +88,60 @@ elabRecord :: ElabInfo -> SyntaxInfo -> FC -> Name ->
8888 PTerm -> Name -> PTerm -> Idris ()
8989elabRecord info syn fc tyn ty cn cty
9090 = do elabData info syn fc (PDatadecl tyn ty [(cn, cty, fc)])
91+ cty <- implicit syn cn cty
92+ i <- get
93+ cty <- case lookupTy Nothing cn (tt_ctxt i) of
94+ [t] -> return (delab i t)
95+ _ -> fail "Something went inexplicably wrong"
96+ cimp <- case lookupCtxt Nothing cn (idris_implicits i) of
97+ [imps] -> return imps
98+ let ptys = getProjs [] (renameBs cimp cty)
99+ let recty = getRecTy cty
100+ logLvl 6 $ show (recty, ptys)
101+ let substs = map (\ (n, _) -> (n, PApp fc (PRef fc n)
102+ [pexp (PRef fc rec)])) ptys
103+ let ptpos = zip ptys [0..]
104+ decls <- mapM (mkProj recty substs cimp) ptpos
105+ mapM_ (elabDecl info) (concat decls)
106+ where
107+
108+ renameBs (PImp _ _ _ _ : ps) (PPi p n ty s)
109+ = PPi p (mkImp n) ty (renameBs ps (substMatch n (PRef fc (mkImp n)) s))
110+ renameBs (_:ps) (PPi p n ty s) = PPi p n ty (renameBs ps s)
111+ renameBs _ t = t
112+
113+ getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
114+ getProjs acc r = reverse acc
115+
116+ getRecTy (PPi _ n ty s) = getRecTy s
117+ getRecTy t = t
118+
119+ rec = MN 0 "rec"
120+
121+ mkp (UN n) = MN 0 ("p_" ++ n)
122+ mkp (MN 0 n) = MN 0 ("p_" ++ n)
123+ mkp (NS n s) = NS (mkp n) s
124+
125+ mkImp (UN n) = UN ("implicit_" ++ n)
126+ mkImp (MN 0 n) = MN 0 ("implicit_" ++ n)
127+ mkImp (NS n s) = NS (mkImp n) s
128+
129+ mkProj recty substs cimp ((pn, pty), pos)
130+ = do let pfnTy = PTy defaultSyntax fc [] pn
131+ (PPi expl rec recty
132+ (substMatches substs pty))
133+ let pls = repeat Placeholder
134+ let before = pos
135+ let after = length substs - (pos + 1)
136+ let args = take before pls ++ PRef fc (mkp pn) : take after pls
137+ let iargs = map implicitise (zip cimp args)
138+ let lhs = PApp fc (PRef fc pn)
139+ [pexp (PApp fc (PRef fc cn) iargs)]
140+ let rhs = PRef fc (mkp pn)
141+ let pclause = PClause pn lhs [] rhs []
142+ return [pfnTy, PClauses fc [] pn [pclause]]
143+
144+ implicitise (pa, t) = pa { getTm = t }
91145
92146elabCon :: ElabInfo -> SyntaxInfo -> Name -> (Name, PTerm, FC) -> Idris (Name, Type)
93147elabCon info syn tn (n, t_in, fc)
src/Idris/ElabTerm.hs+3−3
@@ -143,6 +143,7 @@ elab ist info pattern tcgen fn tm
143143 [] -> False
144144 _ -> True
145145 -- this is to stop us resolve type classes recursively
146+ -- trace (show (n, guarded)) $
146147 if (tcname n && ina) then erun fc $ patvar n
147148 else if (defined && not guarded)
148149 then do apply (Var n) []; solve
@@ -226,9 +227,8 @@ elab ist info pattern tcgen fn tm
226227 (elabArgs (ina || not isinf, guarded)
227228 [] False (reverse ns')
228229 (map (\x -> (lazyarg x, getTm x)) (reverse eargs))))
229−-- (try (do apply2 (Var f) (map (toElab' (ina || not isinf)) args))
230− (do apply_elab f (map (toElab (ina || not isinf, guarded)) args)
231− solve)
230+ (do apply_elab f (map (toElab (ina || not isinf, guarded)) args)
231+ solve)
232232 ivs' <- get_instances
233233 when (not pattern || (ina && not tcgen)) $
234234 mapM_ (\n -> do focus n
src/Idris/Parser.hs+5−1
@@ -945,8 +945,12 @@ pRecord syn = try (do acc <- pAccessibility
945945 tyn_in <- pfName; ty <- pTSig syn
946946 let tyn = expandNS syn tyn_in
947947 reserved "where"
948+ open_block
949+ push_indent
948950 (cn, cty, _) <- pConstructor syn
949− pTerminator
951+ pKeepTerminator
952+ pop_indent
953+ close_block
950954 accData acc tyn [cn]
951955 return $ PRecord syn fc tyn ty cn cty)
952956