@@ -147,7 +147,7 @@ elabData info syn doc fc codata (PDatadecl n t_in dcons)
147 ttag <- getName
147 ttag <- getName
148 i <- getIState
148 i <- getIState
149 let as = map (const Nothing) (getArgTys cty)
149 let as = map (const Nothing) (getArgTys cty)
150− let params = findParams (zip as (repeat True)) (map snd cons)
150+ let params = findParams (map snd cons)
151 logLvl 2 $ "Parameters : " ++ show params
151 logLvl 2 $ "Parameters : " ++ show params
152 putIState (i { idris_datatypes = addDef n (TI (map fst cons) codata params)
152 putIState (i { idris_datatypes = addDef n (TI (map fst cons) codata params)
153 (idris_datatypes i) })
153 (idris_datatypes i) })
@@ -161,32 +161,53 @@ elabData info syn doc fc codata (PDatadecl n t_in dcons)
162 -- parameters are names which are unchanged across the structure,
162 -- parameters are names which are unchanged across the structure,
163 -- which appear exactly once in the return type of a constructor
163 -- which appear exactly once in the return type of a constructor
164− findParams :: [(Maybe Name, Bool)] -> [Type] -> [Int]
164+
165− findParams ps [] = mapMaybe (\ ((x, y), n) ->
165+ -- First, find all applications of the constructor, then check over
166− if y then Just n else Nothing)
166+ -- them for repeated arguments
168− findParams ps (t : ts) = findParams (updateParams ps t) ts
168+ findParams :: [Type] -> [Int]
169−
169+ findParams ts = let allapps = concatMap getDataApp ts in
170− updateParams ps (Bind n (Pi t) sc)
170+ paramPos allapps
171− = updateParams (updateParams ps (instantiate (P Bound n t) sc)) t
171+
172− updateParams ps tm@(App f a)
172+ paramPos [] = []
173+ paramPos (args : rest)
174+ = dropNothing $ keepSame (zip [0..] args) rest
177+ dropNothing ((x, Nothing) : ts) = dropNothing ts
178+ dropNothing ((x, _) : ts) = x : dropNothing ts
180+ keepSame :: [(Int, Maybe Name)] -> [[Maybe Name]] ->
183+ keepSame as (args : rest) = keepSame (update as args) rest
187+ update ((n, Just x) : as) (Just x' : args)
188+ | x == x' = (n, Just x) : update as args
189+ update ((n, _) : as) (_ : args) = (n, Nothing) : update as args
191+ getDataApp :: Type -> [[Maybe Name]]
192+ getDataApp f@(App _ _)
173− | (P _ fn _, args) <- unApply tm
193+ | (P _ d _, args) <- unApply f
174− = if fn == n
194+ = if (d == n) then [mParam args args] else []
175− then updateParamsA ps args (tail args)
195+ getDataApp (Bind n (Pi t) sc)
176− else updateParams (updateParams ps f) a
196+ = getDataApp t ++ getDataApp (instantiate (P Bound n t) sc)
177− | otherwise = updateParams (updateParams ps f) a
197+ getDataApp _ = []
178− updateParams ps _ = ps
198+
179−
199+ -- keep the arguments which are single names, which don't appear
180− updateParamsA ((mn, _) : ns) (p@(P _ n' _) : args) all
200+ -- elsewhere
203+ mParam args (P Bound n _ : rest)
205+ = Just n : mParam args rest
206+ where count n [] = 0
181− | n' `elem` concatMap freeNames all
208+ | n `elem` freeNames t = 1 + count n ts
182− = (mn, False) : updateParamsA ns args (p : all)
209+ | otherwise = count n ts
183− updateParamsA ((Nothing, b) : ns) (p@(P _ n' _) : args) all
210+ mParam args (_ : rest) = Nothing : mParam args rest
184− = (Just n', b) : updateParamsA ns args (p : all)
185− updateParamsA ((Just p, b) : ns) (tm@(P _ n' _) : args) all
186− = (Just n', b && p == n') : updateParamsA ns args (tm : all)
187− updateParamsA ((mn, _) : ns) (p : args) all
188− = (mn, False) : updateParamsA ns args (p : all)
189− updateParamsA ps args all = ps
191-- | Elaborate a type provider
212-- | Elaborate a type provider
192elabProvider :: ElabInfo -> SyntaxInfo -> FC -> Name -> PTerm -> PTerm -> Idris ()
213elabProvider :: ElabInfo -> SyntaxInfo -> FC -> Name -> PTerm -> PTerm -> Idris ()