1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
11import System.Console.Haskeline
12import Control.Monad.State
18import qualified Epic.Epic as E
20data IOption = IOption { opt_logLevel :: Int,
22 opt_typeintype :: Bool,
30defaultOpts = IOption 0 False False True False True True
32-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
33-- without typechecking).
34-- This will include all the functions and data declarations, plus fixity declarations
37data IState = IState { tt_ctxt :: Context,
38 idris_constraints :: [(UConstraint, FC)],
39 idris_infixes :: [FixDecl],
40 idris_implicits :: Ctxt [PArg],
41 idris_statics :: Ctxt [Bool],
42 idris_classes :: Ctxt ClassInfo,
43 idris_dsls :: Ctxt DSL,
44 idris_optimisation :: Ctxt OptInfo,
45 idris_datatypes :: Ctxt TypeInfo,
46 idris_patdefs :: Ctxt [(Term, Term)], -- not exported
47 idris_flags :: Ctxt [FnOpt],
49 idris_options :: IOption,
51 idris_metavars :: [Name],
52 syntax_rules :: [Syntax],
53 syntax_keywords :: [String],
54 imported :: [FilePath],
55 idris_prims :: [(Name, ([E.Name], E.Term))],
56 idris_objs :: [FilePath],
57 idris_libs :: [String],
58 idris_hdrs :: [String],
59 last_proof :: Maybe (Name, [String]),
61 lastParse :: Maybe Name,
62 indent_stack :: [Int],
63 brace_stack :: [Maybe Int],
64 hide_list :: [(Name, Maybe Accessibility)],
65 default_access :: Accessibility,
66 ibc_write :: [IBCWrite],
67 compiled_so :: Maybe String
70-- information that needs writing for the current module's .ibc file
71data IBCWrite = IBCFix FixDecl
84 | IBCAccess Name Accessibility
85 | IBCTotal Name Totality
86 | IBCFlags Name [FnOpt]
87 | IBCDef Name -- i.e. main context
90idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
91 emptyContext emptyContext emptyContext emptyContext emptyContext
92 "" defaultOpts 6 [] [] [] [] [] [] [] []
93 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
95-- The monad for the main REPL - reading and processing files and updating
96-- global state (hence the IO inner monad).
97type Idris = StateT IState (InputT IO)
99getContext :: Idris Context
100getContext = do i <- get; return (tt_ctxt i)
102getObjectFiles :: Idris [FilePath]
103getObjectFiles = do i <- get; return (idris_objs i)
105addObjectFile :: FilePath -> Idris ()
106addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
108getLibs :: Idris [String]
109getLibs = do i <- get; return (idris_libs i)
111addLib :: String -> Idris ()
112addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
114addHdr :: String -> Idris ()
115addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
117setFlags :: Name -> [FnOpt] -> Idris ()
118setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
120setAccessibility :: Name -> Accessibility -> Idris ()
123 let ctxt = setAccess n a (tt_ctxt i)
124 put (i { tt_ctxt = ctxt })
126setTotality :: Name -> Totality -> Idris ()
129 let ctxt = setTotal n a (tt_ctxt i)
130 put (i { tt_ctxt = ctxt })
132addIBC :: IBCWrite -> Idris ()
135 when (notDef (ibc_write i)) $
136 put (i { ibc_write = ibc : ibc_write i })
137 where notDef [] = True
138 notDef (IBCDef n': is) | n == n' = False
139 notDef (_ : is) = notDef is
140addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
143clearIBC = do i <- get; put (i { ibc_write = [] })
145getHdrs :: Idris [String]
146getHdrs = do i <- get; return (idris_hdrs i)
148setErrLine :: Int -> Idris ()
149setErrLine x = do i <- get;
151 Nothing -> put (i { errLine = Just x })
155clearErr = do i <- get
156 put (i { errLine = Nothing })
158getSO :: Idris (Maybe String)
160 return (compiled_so i)
162setSO :: Maybe String -> Idris ()
164 put (i { compiled_so = s })
166getIState :: Idris IState
169putIState :: IState -> Idris ()
173getName = do i <- get;
174 let idx = idris_name i;
175 put (i { idris_name = idx + 1 })
178checkUndefined :: FC -> Name -> Idris ()
181 case lookupTy Nothing n i of
182 (_:_) -> fail $ show fc ++ ":" ++
183 show n ++ " already defined"
186setContext :: Context -> Idris ()
187setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
189updateContext :: (Context -> Context) -> Idris ()
190updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
192addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
193addConstraints fc (v, cs)
196 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
198 let ics = zip cs (repeat fc) ++ idris_constraints i
199 put (i { tt_ctxt = ctxt', idris_constraints = ics })
201addDeferred :: [(Name, Type)] -> Idris ()
202addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
204 put (i { idris_metavars = map fst ns ++ idris_metavars i })
205 where tidyNames used (Bind (MN i x) b sc)
206 = let n' = uniqueName (UN x) used in
207 Bind n' b $ tidyNames (n':used) sc
208 tidyNames used (Bind n b sc)
209 = let n' = uniqueName n used in
210 Bind n' b $ tidyNames (n':used) sc
213solveDeferred :: Name -> Idris ()
214solveDeferred n = do i <- get
215 put (i { idris_metavars = idris_metavars i \\ [n] })
217iputStrLn :: String -> Idris ()
218iputStrLn = liftIO . putStrLn
220iWarn :: FC -> String -> Idris ()
221iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
223setLogLevel :: Int -> Idris ()
224setLogLevel l = do i <- get
225 let opts = idris_options i
226 let opt' = opts { opt_logLevel = l }
227 put (i { idris_options = opt' } )
230logLevel = do i <- get
231 return (opt_logLevel (idris_options i))
235 return (opt_repl (idris_options i))
237setREPL :: Bool -> Idris ()
238setREPL t = do i <- get
239 let opts = idris_options i
240 let opt' = opts { opt_repl = t }
241 put (i { idris_options = opt' })
245 return (opt_verbose (idris_options i))
247setVerbose :: Bool -> Idris ()
248setVerbose t = do i <- get
249 let opts = idris_options i
250 let opt' = opts { opt_verbose = t }
251 put (i { idris_options = opt' })
253typeInType :: Idris Bool
254typeInType = do i <- get
255 return (opt_typeintype (idris_options i))
257setTypeInType :: Bool -> Idris ()
258setTypeInType t = do i <- get
259 let opts = idris_options i
260 let opt' = opts { opt_typeintype = t }
261 put (i { idris_options = opt' })
263coverage :: Idris Bool
264coverage = do i <- get
265 return (opt_coverage (idris_options i))
267setCoverage :: Bool -> Idris ()
268setCoverage t = do i <- get
269 let opts = idris_options i
270 let opt' = opts { opt_coverage = t }
271 put (i { idris_options = opt' })
275 return (opt_showimp (idris_options i))
277setImpShow :: Bool -> Idris ()
278setImpShow t = do i <- get
279 let opts = idris_options i
280 let opt' = opts { opt_showimp = t }
281 put (i { idris_options = opt' })
283logLvl :: Int -> String -> Idris ()
284logLvl l str = do i <- get
285 let lvl = opt_logLevel (idris_options i)
287 $ do liftIO (putStrLn str)
288 put (i { idris_log = idris_log i ++ str ++ "\n" } )
290iLOG :: String -> Idris ()
293noErrors :: Idris Bool
294noErrors = do i <- get
296 Nothing -> return True
299setTypeCase :: Bool -> Idris ()
300setTypeCase t = do i <- get
301 let opts = idris_options i
302 let opt' = opts { opt_typecase = t }
303 put (i { idris_options = opt' })
305-- Commands in the REPL
307data Command = Quit | Help | Eval PTerm | Check PTerm | Reload | Edit
308 | Compile String | Execute | ExecVal PTerm
309 | Metavars | Prove Name | AddProof | Universes
311 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name | Info Name
314-- Parsed declarations
316data Fixity = Infixl { prec :: Int }
317 | Infixr { prec :: Int }
318 | InfixN { prec :: Int }
319 | PrefixN { prec :: Int }
322deriving instance Binary Fixity
325instance Show Fixity where
326 show (Infixl i) = "infixl " ++ show i
327 show (Infixr i) = "infixr " ++ show i
328 show (InfixN i) = "infix " ++ show i
329 show (PrefixN i) = "prefix " ++ show i
331data FixDecl = Fix Fixity String
334deriving instance Binary FixDecl
337instance Ord FixDecl where
338 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
341data Static = Static | Dynamic
344deriving instance Binary Static
347-- Mark bindings with their explicitness, and laziness
348data Plicity = Imp { plazy :: Bool,
350 | Exp { plazy :: Bool,
352 | Constraint { plazy :: Bool,
357deriving instance Binary Plicity
360impl = Imp False Dynamic
361expl = Exp False Dynamic
362constraint = Constraint False Static
364data FnOpt = Inlinable | TotalFn | TCGen
367deriving instance Binary FnOpt
372inlinable :: FnOpts -> Bool
373inlinable = elem Inlinable
375data PDecl' t = PFix FC Fixity [String] -- fixity declaration
376 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
377 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
378 | PData SyntaxInfo FC (PData' t) -- data declaration
379 | PParams FC [(Name, t)] [PDecl' t] -- params block
380 | PNamespace String [PDecl' t] -- new namespace
381 | PRecord SyntaxInfo FC Name t Name t -- record declaration
382 | PClass SyntaxInfo FC
385 [(Name, t)] -- parameters
386 [PDecl' t] -- declarations
387 | PInstance SyntaxInfo FC [t] -- constraints
390 t -- full instance type
394 | PDirective (Idris ())
397data PClause' t = PClause Name t [t] t [PDecl' t]
398 | PWith Name t [t] t [PDecl' t]
399 | PClauseR [t] t [PDecl' t]
400 | PWithR [t] t [PDecl' t]
403data PData' t = PDatadecl { d_name :: Name,
405 d_cons :: [(Name, t, FC)] }
408-- Handy to get a free function for applying PTerm -> PTerm functions
409-- across a program, by deriving Functor
411type PDecl = PDecl' PTerm
412type PData = PData' PTerm
413type PClause = PClause' PTerm
415-- get all the names declared in a decl
417declared :: PDecl -> [Name]
418declared (PFix _ _ _) = []
419declared (PTy _ _ _ n t) = [n]
420declared (PClauses _ _ n _) = [] -- not a declaration
421declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
422 where fstt (a, _, _) = a
423declared (PParams _ _ ds) = concatMap declared ds
424declared (PNamespace _ ds) = concatMap declared ds
425-- declared (PImport _) = []
427updateN :: [(Name, Name)] -> Name -> Name
428updateN ns n | Just n' <- lookup n ns = n'
431updateNs :: [(Name, Name)] -> PTerm -> PTerm
433updateNs ns t = mapPT updateRef t
434 where updateRef (PRef fc f) = PRef fc (updateN ns f)
437-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
439-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
440-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
441-- where updateCNs ns (PClause n l ts r ds)
442-- = PClause (updateN ns n) (fmap (updateNs ns) l)
443-- (map (fmap (updateNs ns)) ts)
444-- (fmap (updateNs ns) r)
445-- (map (updateDNs ns) ds)
448-- High level language terms
450data PTerm = PQuote Raw
452 | PLam Name PTerm PTerm
453 | PPi Plicity Name PTerm PTerm
454 | PLet Name PTerm PTerm PTerm
455 | PTyped PTerm PTerm -- term with explicit type
456 | PApp FC PTerm [PArg]
457 | PCase FC PTerm [(PTerm, PTerm)]
463 | PPair FC PTerm PTerm
464 | PDPair FC PTerm PTerm PTerm
465 | PAlternative [PTerm]
466 | PHidden PTerm -- irrelevant or hidden pattern
475 | PTactics [PTactic] -- as PProof, but no auto solving
476 | PElabError String -- error to report on elaboration
477 | PImpossible -- special case for declaring when an LHS can't typecheck
480deriving instance Binary PTerm
483mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
484mapPT f t = f (mpt t) where
485 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
486 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
487 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
488 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
489 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
490 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
491 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
492 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
493 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
494 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
495 mpt (PHidden t) = PHidden (mapPT f t)
496 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
497 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
498 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
502data PTactic' t = Intro [Name] | Intros | Focus Name
503 | Refine Name [Bool] | Rewrite t | LetTac Name t
504 | Exact t | Compute | Trivial
507 | ProofState | ProofTerm | Undo
508 | Try (PTactic' t) (PTactic' t)
509 | TSeq (PTactic' t) (PTactic' t)
511 deriving (Show, Eq, Functor)
513deriving instance Binary PTactic'
516type PTactic = PTactic' PTerm
518data PDo' t = DoExp FC t
523 deriving (Eq, Functor)
525deriving instance Binary PDo'
530-- The priority gives a hint as to elaboration order. Best to elaborate
531-- things early which will help give a more concrete type to other
532-- variables, e.g. a before (interpTy a).
534data PArg' t = PImp { priority :: Int,
535 lazyarg :: Bool, pname :: Name, getTm :: t }
536 | PExp { priority :: Int,
537 lazyarg :: Bool, getTm :: t }
538 | PConstraint { priority :: Int,
539 lazyarg :: Bool, getTm :: t }
540 deriving (Show, Eq, Functor)
542deriving instance Binary PArg'
547pconst = PConstraint 0 False
549type PArg = PArg' PTerm
553data ClassInfo = CI { instanceName :: Name,
554 class_methods :: [(Name, PTerm)],
555 class_defaults :: [(Name, Name)], -- method name -> default impl
556 class_params :: [Name] }
559deriving instance Binary ClassInfo
562data OptInfo = Optimise { collapsible :: Bool,
563 forceable :: [Int], -- argument positions
567deriving instance Binary OptInfo
571data TypeInfo = TI { con_names :: [Name] }
574deriving instance Binary TypeInfo
577-- Syntactic sugar info
579data DSL' t = DSL { dsl_bind :: t,
584 index_first :: Maybe t,
585 index_next :: Maybe t,
586 dsl_lambda :: Maybe t,
589 deriving (Show, Functor)
591deriving instance Binary DSL'
596data SynContext = PatternSyntax | TermSyntax | AnySyntax
599deriving instance Binary SynContext
602data Syntax = Rule [SSymbol] PTerm SynContext
605deriving instance Binary Syntax
608data SSymbol = Keyword Name
614deriving instance Binary SSymbol
617initDSL = DSL (PRef f (UN ">>="))
618 (PRef f (UN "return"))
626 where f = FC "(builtin)" 0
628data SyntaxInfo = Syn { using :: [(Name, PTerm)],
629 syn_params :: [(Name, PTerm)],
630 syn_namespace :: [String],
632 decoration :: Name -> Name,
637defaultSyntax = Syn [] [] [] [] id False initDSL
639--- Pretty printing declarations and terms
641instance Show PTerm where
642 show tm = showImp False tm
644instance Show PDecl where
645 show (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
646 show (PTy _ _ _ n ty) = show n ++ " : " ++ show ty
647 show (PClauses _ _ n c) = showSep "\n" (map show c)
648 show (PData _ _ d) = show d
650instance Show PClause where
651 show c = showCImp True c
653instance Show PData where
654 show d = showDImp False d
656showCImp :: Bool -> PClause -> String
657showCImp impl (PClause n l ws r w)
658 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
659 ++ " where " ++ show w
662 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
663showCImp impl (PWith n l ws r w)
664 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
665 ++ " { " ++ show w ++ " } "
668 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
671showDImp :: Bool -> PData -> String
672showDImp impl (PDatadecl n ty cons)
673 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
675 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
677getImps :: [PArg] -> [(Name, PTerm)]
679getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
680getImps (_ : xs) = getImps xs
682getExps :: [PArg] -> [PTerm]
684getExps (PExp _ _ tm : xs) = tm : getExps xs
685getExps (_ : xs) = getExps xs
687getConsts :: [PArg] -> [PTerm]
689getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
690getConsts (_ : xs) = getConsts xs
692getAll :: [PArg] -> [PTerm]
695showImp :: Bool -> PTerm -> String
696showImp impl tm = se 10 tm where
697 se p (PQuote r) = "![" ++ show r ++ "]"
698 se p (PRef _ n) = if impl then show n
700 where showbasic n@(UN _) = show n
701 showbasic (MN _ s) = s
702 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
703 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
704 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
706 se p (PPi (Exp l s) n ty sc)
707 | n `elem` allNamesIn sc = bracket p 2 $
708 if l then "|(" else "(" ++
709 show n ++ " : " ++ se 10 ty ++
712 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
714 Static -> "[static] "
716 se p (PPi (Imp l s) n ty sc)
717 | impl = bracket p 2 $ if l then "|{" else "{" ++
718 show n ++ " : " ++ se 10 ty ++
719 "} " ++ st ++ "-> " ++ se 10 sc
720 | otherwise = se 10 sc
722 Static -> "[static] "
724 se p (PPi (Constraint _ _) n ty sc)
725 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
726 se p (PApp _ (PRef _ f) [])
728 se p (PApp _ (PRef _ op@(UN (f:_))) args)
729 | length (getExps args) == 2 && not impl && not (isAlpha f)
730 = let [l, r] = getExps args in
731 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
733 = let args = getExps as in
734 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
735 else concatMap seArg args
736 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
737 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
738 se p (PHidden tm) = "." ++ se 0 tm
739 se p (PRefl _) = "refl"
740 se p (PResolveTC _) = "resolvetc"
741 se p (PTrue _) = "()"
742 se p (PFalse _) = "_|_"
743 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
744 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
745 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
746 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
747 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
749 se p (PConstant c) = show c
750 se p (PProof ts) = "proof { " ++ show ts ++ "}"
751 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
752 se p (PMetavar n) = "?" ++ show n
753 se p (PReturn f) = "return"
754 se p PImpossible = "impossible"
755 se p Placeholder = "_"
756 se p (PDoBlock _) = "do block show not implemented"
757 se p (PElabError s) = s
758-- se p x = "Not implemented"
760 sArg (PImp _ _ n tm) = siArg (n, tm)
761 sArg (PExp _ _ tm) = seArg tm
762 sArg (PConstraint _ _ tm) = scArg tm
764 seArg arg = " " ++ se 0 arg
765 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
766 scArg val = " {{" ++ se 10 val ++ "}}"
768 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
771allNamesIn :: PTerm -> [Name]
772allNamesIn tm = nub $ ni [] tm
775 | not (n `elem` env) = [n]
776 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
777 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
778 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
779 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
780 ni env (PHidden tm) = ni env tm
781 ni env (PEq _ l r) = ni env l ++ ni env r
782 ni env (PTyped l r) = ni env l ++ ni env r
783 ni env (PPair _ l r) = ni env l ++ ni env r
784 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
785 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
786 ni env (PAlternative ls) = concatMap (ni env) ls
789namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
790namesIn uvars ist tm = nub $ ni [] tm
794 = case lookupTy Nothing n (tt_ctxt ist) of
796 _ -> if n `elem` (map fst uvars) then [n] else []
797 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
798 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
799 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
800 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
801 ni env (PEq _ l r) = ni env l ++ ni env r
802 ni env (PTyped l r) = ni env l ++ ni env r
803 ni env (PPair _ l r) = ni env l ++ ni env r
804 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
805 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
806 ni env (PAlternative as) = concatMap (ni env) as
807 ni env (PHidden tm) = ni env tm
810-- For inferring types of things
814inferTy = MN 0 "__Infer"
815inferCon = MN 0 "__infer"
816inferDecl = PDatadecl inferTy
818 [(inferCon, PPi impl (MN 0 "A") PSet (
819 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
820 (PRef bi inferTy)), bi)]
822infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
823infP = P (TCon 6 0) inferTy (Set (UVal 0))
825getInferTerm, getInferType :: Term -> Term
826getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
827getInferTerm (App (App _ _) tm) = tm
828getInferTerm tm = error ("getInferTerm " ++ show tm)
830getInferType (Bind n b sc) = Bind n b $ getInferType sc
831getInferType (App (App _ ty) _) = ty
833-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
835primNames = [unitTy, unitCon,
836 falseTy, pairTy, pairCon,
837 eqTy, eqCon, inferTy, inferCon]
839unitTy = MN 0 "__Unit"
841unitDecl = PDatadecl unitTy PSet
842 [(unitCon, PRef bi unitTy, bi)]
844falseTy = MN 0 "__False"
845falseDecl = PDatadecl falseTy PSet []
847pairTy = MN 0 "__Pair"
848pairCon = MN 0 "__MkPair"
849pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
850 [(pairCon, PPi impl (n "A") PSet (
851 PPi impl (n "B") PSet (
852 PPi expl (n "a") (PRef bi (n "A")) (
853 PPi expl (n "b") (PRef bi (n "B"))
854 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
855 pexp (PRef bi (n "B"))])))), bi)]
860eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
861 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
863 [(eqCon, PPi impl (n "a") PSet (
864 PPi impl (n "x") (PRef bi (n "a"))
865 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
866 pimp (n "b") Placeholder,
867 pexp (PRef bi (n "x")),
868 pexp (PRef bi (n "x"))])), bi)]
871-- Defined in builtins.idr
873existsCon = UN "Ex_intro"
875piBind :: [(Name, PTerm)] -> PTerm -> PTerm
877piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
879tcname (UN ('@':_)) = True
880tcname (NS n _) = tcname n
883-- Dealing with parameters
885expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
886expandParams dec ps ns tm = en tm
888 -- if we shadow a name (say in a lambda binding) that is used in a call to
889 -- a lifted function, we need access to both names - once in the scope of the
890 -- binding and once to call the lifted functions. So we'll explicitly shadow
891 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
894 mkShadow (UN n) = MN 0 n
895 mkShadow (MN i n) = MN (i+1) n
896 mkShadow (NS x s) = NS (mkShadow x) s
899 | n `elem` map fst ps
900 = let n' = mkShadow n in
901 PLam n' (en t) (en (shadow n n' s))
902 | otherwise = PLam n (en t) (en s)
904 | n `elem` map fst ps
905 = let n' = mkShadow n in
906 PPi p n' (en t) (en (shadow n n' s))
907 | otherwise = PPi p n (en t) (en s)
909 | n `elem` map fst ps
910 = let n' = mkShadow n in
911 PLet n' (en ty) (en v) (en (shadow n n' s))
912 | otherwise = PLet n (en ty) (en v) (en s)
913 en (PEq f l r) = PEq f (en l) (en r)
914 en (PTyped l r) = PTyped (en l) (en r)
915 en (PPair f l r) = PPair f (en l) (en r)
916 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
917 en (PAlternative as) = PAlternative (map en as)
918 en (PHidden t) = PHidden (en t)
919 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
920 en (PProof ts) = PProof (map (fmap en) ts)
921 en (PTactics ts) = PTactics (map (fmap en) ts)
924 | n `elem` ns = PQuote (Var (dec n))
925 en (PApp fc (PRef fc' n) as)
926 | n `elem` ns = PApp fc (PRef fc' (dec n))
927 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
929 | n `elem` ns = PApp fc (PRef fc (dec n))
930 (map (pexp . (PRef fc)) (map fst ps))
931 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
932 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
935expandParamsD :: IState ->
936 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
937expandParamsD ist dec ps ns (PTy syn fc o n ty)
939 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
940 else PTy syn fc o n (expandParams dec ps ns ty)
941expandParamsD ist dec ps ns (PClauses fc opts n cs)
942 = let n' = if n `elem` ns then dec n else n in
943 PClauses fc opts n' (map expandParamsC cs)
945 expandParamsC (PClause n lhs ws rhs ds)
946 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
947 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
948 n' = if n `elem` ns then dec n else n in
949 PClause n' (expandParams dec ps'' ns lhs)
950 (map (expandParams dec ps'' ns) ws)
951 (expandParams dec ps'' ns rhs)
952 (map (expandParamsD ist dec ps'' ns) ds)
953 expandParamsC (PWith n lhs ws wval ds)
954 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
955 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
956 n' = if n `elem` ns then dec n else n in
957 PWith n' (expandParams dec ps'' ns lhs)
958 (map (expandParams dec ps'' ns) ws)
959 (expandParams dec ps'' ns wval)
960 (map (expandParamsD ist dec ps'' ns) ds)
961 updateps yn nm [] = []
962 updateps yn nm (((a, t), i):as)
963 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
964 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
966expandParamsD ist dec ps ns d = d
968-- Calculate a priority for a type, for deciding elaboration order
969-- * if it's just a type variable or concrete type, do it early (0)
970-- * if there's only type variables and injective constructors, do it next (1)
971-- * if there's a function type, next (2)
972-- * finally, everything else (3)
974getPriority :: IState -> PTerm -> Int
975getPriority i tm = pri tm
978 case lookupP Nothing n (tt_ctxt i) of
979 ((P (DCon _ _) _ _):_) -> 1
980 ((P (TCon _ _) _ _):_) -> 1
982 [] -> 0 -- must be locally bound, if it's not an error...
983 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
987 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
988 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
989 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
990 pri (PTyped l r) = pri l
991 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
992 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
993 pri (PAlternative as) = maximum (map pri as)
994 pri (PConstant _) = 0
998-- Dealing with implicit arguments
1000-- Add implicit Pi bindings for any names in the term which appear in an
1001-- argument position.
1003-- This has become a right mess already. Better redo it some time...
1005implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1008 let (tm', impdata) = implicitise syn i ptm
1009 let (tm'', spos) = findStatics i tm'
1010 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1012 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1014 put (i { idris_statics = addDef n spos (idris_statics i) })
1015 addIBC (IBCStatic n)
1018implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1019implicitise syn ist tm
1020 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1021 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1023 then (tm, reverse declimps)
1024 else implicitise syn ist (pibind uvars ns tm)
1027 pvars = syn_params syn
1029 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1030 | otherwise = x : dropAll xs ys
1033 imps top env (PApp _ f as)
1034 = do (decls, ns) <- get
1035 let isn = concatMap (namesIn uvars ist) (map getTm as)
1036 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1037 imps top env (PPi (Imp l _) n ty sc)
1038 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1040 put (PImp (getPriority ist ty) l n ty : decls,
1041 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1042 imps True (n:env) sc
1043 imps top env (PPi (Exp l _) n ty sc)
1044 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1045 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1047 (decls, ns) <- get -- ignore decls in HO types
1048 put (PExp (getPriority ist ty) l ty : decls,
1049 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1050 imps True (n:env) sc
1051 imps top env (PPi (Constraint l _) n ty sc)
1052 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1053 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1055 (decls, ns) <- get -- ignore decls in HO types
1056 put (PConstraint 10 l ty : decls,
1057 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1058 imps True (n:env) sc
1059 imps top env (PEq _ l r)
1060 = do (decls, ns) <- get
1061 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1062 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1063 imps top env (PTyped l r)
1065 imps top env (PPair _ l r)
1066 = do (decls, ns) <- get
1067 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1068 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1069 imps top env (PDPair _ (PRef _ n) t r)
1070 = do (decls, ns) <- get
1071 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1072 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1073 imps top env (PDPair _ l t r)
1074 = do (decls, ns) <- get
1075 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1077 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1078 imps top env (PAlternative as)
1079 = do (decls, ns) <- get
1080 let isn = concatMap (namesIn uvars ist) as
1081 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1082 imps top env (PLam n ty sc)
1083 = do imps False env ty
1084 imps False (n:env) sc
1085 imps top env (PHidden tm) = imps False env tm
1086 imps top env _ = return ()
1088 pibind using [] sc = sc
1089 pibind using (n:ns) sc
1090 = case lookup n using of
1091 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1092 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1094-- Add implicit arguments in function calls
1096addImpl :: IState -> PTerm -> PTerm
1097addImpl ist ptm = ai [] ptm
1100 | not (f `elem` env) = aiFn ist fc f []
1101 ai env (PEq fc l r) = let l' = ai env l
1104 ai env (PTyped l r) = let l' = ai env l
1107 ai env (PPair fc l r) = let l' = ai env l
1110 ai env (PDPair fc l t r) = let l' = ai env l
1114 ai env (PAlternative as) = let as' = map (ai env) as in
1116 ai env (PApp fc (PRef _ f) as)
1117 | not (f `elem` env)
1118 = let as' = map (fmap (ai env)) as in
1120 ai env (PApp fc f as) = let f' = ai env f
1121 as' = map (fmap (ai env)) as in
1123 ai env (PCase fc c os) = let c' = ai env c
1124 os' = map (pmap (ai env)) os in
1126 ai env (PLam n ty sc) = let ty' = ai env ty
1127 sc' = ai (n:env) sc in
1129 ai env (PLet n ty val sc)
1130 = let ty' = ai env ty
1132 sc' = ai (n:env) sc in
1134 ai env (PPi p n ty sc) = let ty' = ai env ty
1135 sc' = ai (n:env) sc in
1137 ai env (PHidden tm) = PHidden (ai env tm)
1138 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1139 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1142aiFn :: IState -> FC -> Name -> [PArg] -> PTerm
1144 | f `elem` primNames = PApp fc (PRef fc f) as
1146 -- This is where namespaces get resolved by adding PAlternative
1147 = case lookupCtxtName Nothing f (idris_implicits ist) of
1148 [(f',ns)] -> mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1149 [] -> if f `elem` idris_metavars ist
1150 then PApp fc (PRef fc f) as
1151 else mkPApp fc (length as) (PRef fc f) as
1152 alts -> PAlternative $
1153 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1154 (insertImpl ns as)) alts
1156 insertImpl :: [PArg] -> [PArg] -> [PArg]
1157 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1158 PExp p l tm : insertImpl ps given
1159 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1160 PConstraint p l tm : insertImpl ps given
1161 insertImpl (PConstraint p l ty : ps) given =
1162 PConstraint p l (PResolveTC fc) : insertImpl ps given
1163 insertImpl (PImp p l n ty : ps) given =
1164 case find n given [] of
1165 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1166 Nothing -> PImp p l n Placeholder : insertImpl ps given
1167 insertImpl expected [] = []
1168 insertImpl _ given = given
1170 find n [] acc = Nothing
1171 find n (PImp _ _ n' t : gs) acc
1172 | n == n' = Just (t, reverse acc ++ gs)
1173 find n (g : gs) acc = find n gs (g : acc)
1176mkPApp fc a f as = let rest = drop a as in
1177 appRest fc (PApp fc f (take a as)) rest
1180 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1182-- Find 'static' argument positions
1183-- (the declared ones, plus any names in argument position in the declared
1185-- FIXME: It's possible that this really has to happen after elaboration
1187findStatics :: IState -> PTerm -> (PTerm, [Bool])
1188findStatics ist tm = let (ns, ss) = fs tm in
1189 runState (pos ns ss tm) []
1190 where fs (PPi p n t sc)
1191 | Static <- pstatic p
1192 = let (ns, ss) = fs sc in
1193 (namesIn [] ist t : ns, namesIn [] ist t ++ n : ss)
1194 | otherwise = let (ns, ss) = fs sc in
1195 (namesIn [] ist t : ns, ss)
1198 inOne n ns = length (filter id (map (elem n) ns)) == 1
1200 pos ns ss (PPi p n t sc)
1201 | n `inOne` ns && elem n ss
1202 = do sc' <- pos ns ss sc
1205 return (PPi (p { pstatic = Static }) n t sc')
1206 | otherwise = do sc' <- pos ns ss sc
1209 return (PPi p n t sc')
1210 pos ns ss t = return t
1212-- Debugging/logging stuff
1214dumpDecls :: [PDecl] -> String
1216dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1218dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1219dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1220dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1221dumpDecl (PData _ _ d) = showDImp True d
1222dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1223dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1224dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1225dumpDecl (PClass _ _ cs n ps ds)
1226 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1227dumpDecl (PInstance _ _ cs n _ t ds)
1228 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1230-- dumpDecl (PImport i) = "import " ++ i
1232-- for 6.12/7 compatibility
1233data EitherErr a b = LeftErr a | RightOK b
1235instance Monad (EitherErr a) where
1238 (LeftErr e) >>= k = LeftErr e
1239 RightOK v >>= k = k v
1241toEither (LeftErr e) = Left e
1242toEither (RightOK ho) = Right ho
1244-- syntactic match of a against b, returning pair of variables in a
1245-- and what they match. Returns the pair that failed if not a match.
1247matchClause :: PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1248matchClause = matchClause' False
1250matchClause' :: Bool -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1251matchClause' names x y = checkRpts $ match (fullApp x) (fullApp y) where
1252 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1254 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1257 match' x y = match (fullApp x) (fullApp y)
1258 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1259 | PConstant (I _) <- getTm x = match (getTm x) x'
1260 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1261 | PConstant (I _) <- getTm x = match (getTm x) x'
1262 match (PApp _ f args) (PApp _ f' args')
1263 | length args == length args'
1264 = do mf <- match' f f'
1265 ms <- zipWithM matchArg args args'
1266 return (mf ++ concat ms)
1267-- match (PRef _ n) (PRef _ n') | n == n' = return []
1268-- | otherwise = Nothing
1269 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1270 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1271 match (PRef _ n) (PRef _ n') | n == n' = return []
1272 match (PRef _ n) tm | not names = return [(n, tm)]
1273 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1276 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1279 match (PTyped l r) x = match l x
1280 match x (PTyped l r) = match x l
1281 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1284 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1287 return (ml ++ mt ++ mr)
1288 match (PAlternative as) (PAlternative as')
1289 = do ms <- zipWithM match' as as'
1291 match a@(PAlternative as) b
1292 = do let ms = zipWith match' as (repeat b)
1293 case (rights (map toEither ms)) of
1296 match (PCase _ _ _) _ = return [] -- lifted out
1297 match (PMetavar _) _ = return [] -- modified
1298 match (PQuote _) _ = return []
1299 match (PProof _) _ = return []
1300 match (PTactics _) _ = return []
1301 match (PRefl _) (PRefl _) = return []
1302 match (PResolveTC _) (PResolveTC _) = return []
1303 match (PTrue _) (PTrue _) = return []
1304 match (PFalse _) (PFalse _) = return []
1305 match (PReturn _) (PReturn _) = return []
1306 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1309 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1312 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1313 mty <- match' ty ty'
1315 return (mt ++ mty ++ ms)
1316 match (PHidden x) (PHidden y) = match' x y
1317 match Placeholder _ = return []
1318 match _ Placeholder = return []
1319 match (PResolveTC _) _ = return []
1320 match a b | a == b = return []
1321 | otherwise = LeftErr (a, b)
1323 checkRpts (RightOK ms) = check ms where
1325 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1328 check (_:xs) = check xs
1330 checkRpts (LeftErr x) = Left x
1332substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1333substMatches [] t = t
1334substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1336substMatch :: Name -> PTerm -> PTerm -> PTerm
1337substMatch n tm t = sm t where
1338 sm (PRef _ n') | n == n' = tm
1339 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1340 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1341 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1342 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1343 sm (PEq f x y) = PEq f (sm x) (sm y)
1344 sm (PTyped x y) = PTyped (sm x) (sm y)
1345 sm (PPair f x y) = PPair f (sm x) (sm y)
1346 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1347 sm (PAlternative as) = PAlternative (map sm as)
1348 sm (PHidden x) = PHidden (sm x)
1351shadow :: Name -> Name -> PTerm -> PTerm
1352shadow n n' t = sm t where
1353 sm (PRef fc x) | n == x = PRef fc n'
1354 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1355 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1356 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1357 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1358 sm (PEq f x y) = PEq f (sm x) (sm y)
1359 sm (PTyped x y) = PTyped (sm x) (sm y)
1360 sm (PPair f x y) = PPair f (sm x) (sm y)
1361 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1362 sm (PAlternative as) = PAlternative (map sm as)
1363 sm (PHidden x) = PHidden (sm x)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list