packages feed

idris 0.12.2 → 0.12.3

raw patch · 495 files changed

+21607/−5485 lines, 495 filessetup-changedbinary-addedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Idris.ASTUtils: known_classes :: Field IState (Ctxt ClassInfo)
- Idris.AbsSyntax: addClass :: Name -> ClassInfo -> Idris ()
- Idris.AbsSyntax: addInstance :: Bool -> Bool -> Name -> Name -> Idris ()
- Idris.AbsSyntax: expandInstanceScope :: t -> t1 -> [(Name, t3)] -> t2 -> PDecl' t3 -> PDecl' t3
- Idris.AbsSyntaxTree: AddClauseFrom :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: AddMissing :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: AddProof :: (Maybe Name) -> Command
- Idris.AbsSyntaxTree: AddProofClauseFrom :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: Apropos :: [String] -> String -> Command
- Idris.AbsSyntaxTree: Browse :: [String] -> Command
- Idris.AbsSyntaxTree: CallsWho :: Name -> Command
- Idris.AbsSyntaxTree: CaseSplitAt :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: ChangeDirectory :: FilePath -> Command
- Idris.AbsSyntaxTree: Check :: PTerm -> Command
- Idris.AbsSyntaxTree: ColourOff :: Command
- Idris.AbsSyntaxTree: ColourOn :: Command
- Idris.AbsSyntaxTree: Compile :: Codegen -> String -> Command
- Idris.AbsSyntaxTree: Core :: PTerm -> Command
- Idris.AbsSyntaxTree: DebugInfo :: Name -> Command
- Idris.AbsSyntaxTree: DebugUnify :: PTerm -> PTerm -> Command
- Idris.AbsSyntaxTree: Defn :: Name -> Command
- Idris.AbsSyntaxTree: DoProofSearch :: Bool -> Bool -> Int -> Name -> [Name] -> Command
- Idris.AbsSyntaxTree: DocStr :: (Either Name Const) -> HowMuchDocs -> Command
- Idris.AbsSyntaxTree: DynamicLink :: FilePath -> Command
- Idris.AbsSyntaxTree: Edit :: Command
- Idris.AbsSyntaxTree: Eval :: PTerm -> Command
- Idris.AbsSyntaxTree: ExecVal :: PTerm -> Command
- Idris.AbsSyntaxTree: Execute :: PTerm -> Command
- Idris.AbsSyntaxTree: Help :: Command
- Idris.AbsSyntaxTree: IBCClass :: Name -> IBCWrite
- Idris.AbsSyntaxTree: IBCInstance :: Bool -> Bool -> Name -> Name -> IBCWrite
- Idris.AbsSyntaxTree: ListDynamic :: Command
- Idris.AbsSyntaxTree: ListErrorHandlers :: Command
- Idris.AbsSyntaxTree: Load :: FilePath -> (Maybe Int) -> Command
- Idris.AbsSyntaxTree: LogCategory :: [LogCat] -> Command
- Idris.AbsSyntaxTree: LogLvl :: Int -> Command
- Idris.AbsSyntaxTree: MakeCase :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: MakeDoc :: String -> Command
- Idris.AbsSyntaxTree: MakeLemma :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: MakeWith :: Bool -> Int -> Name -> Command
- Idris.AbsSyntaxTree: Metavars :: Command
- Idris.AbsSyntaxTree: Missing :: Name -> Command
- Idris.AbsSyntaxTree: ModImport :: String -> Command
- Idris.AbsSyntaxTree: NOP :: Command
- Idris.AbsSyntaxTree: NewDefn :: [PDecl] -> Command
- Idris.AbsSyntaxTree: PClass :: (Docstring (Either Err t)) -> SyntaxInfo -> FC -> [(Name, t)] -> Name -> FC -> [(Name, FC, t)] -> [(Name, Docstring (Either Err t))] -> [(Name, FC)] -> [PDecl' t] -> (Maybe (Name, FC)) -> (Docstring (Either Err t)) -> PDecl' t
- Idris.AbsSyntaxTree: PInstance :: (Docstring (Either Err t)) -> [(Name, Docstring (Either Err t))] -> SyntaxInfo -> FC -> [(Name, t)] -> [Name] -> Accessibility -> FnOpts -> Name -> FC -> [t] -> [(Name, t)] -> t -> (Maybe Name) -> [PDecl' t] -> PDecl' t
- Idris.AbsSyntaxTree: PPrint :: OutputFmt -> Int -> PTerm -> Command
- Idris.AbsSyntaxTree: PReturn :: FC -> PTerm
- Idris.AbsSyntaxTree: Pattelab :: PTerm -> Command
- Idris.AbsSyntaxTree: PrintDef :: Name -> Command
- Idris.AbsSyntaxTree: Proofs :: Command
- Idris.AbsSyntaxTree: Prove :: Bool -> Name -> Command
- Idris.AbsSyntaxTree: Quit :: Command
- Idris.AbsSyntaxTree: RAddInstance :: Name -> Name -> RDeclInstructions
- Idris.AbsSyntaxTree: Reload :: Command
- Idris.AbsSyntaxTree: RmProof :: Name -> Command
- Idris.AbsSyntaxTree: Search :: [String] -> PTerm -> Command
- Idris.AbsSyntaxTree: SetColour :: ColourType -> IdrisColour -> Command
- Idris.AbsSyntaxTree: SetConsoleWidth :: ConsoleWidth -> Command
- Idris.AbsSyntaxTree: SetOpt :: Opt -> Command
- Idris.AbsSyntaxTree: SetPrinterDepth :: (Maybe Int) -> Command
- Idris.AbsSyntaxTree: ShowProof :: Name -> Command
- Idris.AbsSyntaxTree: Spec :: PTerm -> Command
- Idris.AbsSyntaxTree: TCInstance :: PTactic' t
- Idris.AbsSyntaxTree: TestInline :: PTerm -> Command
- Idris.AbsSyntaxTree: TotCheck :: Name -> Command
- Idris.AbsSyntaxTree: TransformInfo :: Name -> Command
- Idris.AbsSyntaxTree: Undefine :: [Name] -> Command
- Idris.AbsSyntaxTree: Universes :: Command
- Idris.AbsSyntaxTree: UnsetOpt :: Opt -> Command
- Idris.AbsSyntaxTree: WHNF :: PTerm -> Command
- Idris.AbsSyntaxTree: Warranty :: Command
- Idris.AbsSyntaxTree: Watch :: Command
- Idris.AbsSyntaxTree: WhoCalls :: Name -> Command
- Idris.AbsSyntaxTree: [class_default_superclasses] :: ClassInfo -> [PDecl]
- Idris.AbsSyntaxTree: [class_defaults] :: ClassInfo -> [(Name, (Name, PDecl))]
- Idris.AbsSyntaxTree: [class_determiners] :: ClassInfo -> [Int]
- Idris.AbsSyntaxTree: [class_instances] :: ClassInfo -> [(Name, Bool)]
- Idris.AbsSyntaxTree: [class_methods] :: ClassInfo -> [(Name, (Bool, FnOpts, PTerm))]
- Idris.AbsSyntaxTree: [class_params] :: ClassInfo -> [Name]
- Idris.AbsSyntaxTree: [dsl_return] :: DSL' t -> t
- Idris.AbsSyntaxTree: [idris_classes] :: IState -> Ctxt ClassInfo
- Idris.AbsSyntaxTree: [instanceCtorName] :: ClassInfo -> Name
- Idris.AbsSyntaxTree: data ClassInfo
- Idris.AbsSyntaxTree: data Command
- Idris.AbsSyntaxTree: instance GHC.Generics.Generic Idris.AbsSyntaxTree.ClassInfo
- Idris.AbsSyntaxTree: instance GHC.Show.Show Idris.AbsSyntaxTree.ClassInfo
- Idris.Core.Elaborate: get_instances :: Elab' aux [Name]
- Idris.Core.Elaborate: instanceArg :: Name -> Elab' aux ()
- Idris.Core.ProofState: Instance :: Name -> Tactic
- Idris.Core.ProofState: [instances] :: ProofState -> [Name]
- Idris.Core.TT: InstanceCtorN :: !Name -> SpecialName
- Idris.Core.TT: InstanceN :: !Name -> [Text] -> SpecialName
- Idris.Core.TT: [tcinstance] :: ImplicitInfo -> Bool
- Idris.Core.TT: sInstanceN :: Name -> [String] -> SpecialName
- Idris.DeepSeq: instance Control.DeepSeq.NFData Idris.AbsSyntaxTree.ClassInfo
- Idris.Docs: ClassDoc :: Name -> d -> [FunDoc' d] -> [(Name, Maybe d)] -> [(Maybe Name, PTerm, (d, [(Name, d)]))] -> [PTerm] -> [PTerm] -> (Maybe (FunDoc' d)) -> Docs' d
- Idris.Docs: NamedInstanceDoc :: Name -> (FunDoc' d) -> Docs' d
- Idris.Elab.Class: elabClass :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> FC -> [(Name, PTerm)] -> Name -> FC -> [(Name, FC, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [(Name, FC)] -> [PDecl] -> Maybe (Name, FC) -> Docstring (Either Err PTerm) -> Idris ()
- Idris.Elab.Class: instance GHC.Show.Show Idris.Elab.Class.MArgTy
- Idris.Elab.Instance: elabInstance :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> [(Name, Docstring (Either Err PTerm))] -> ElabWhat -> FC -> [(Name, PTerm)] -> [Name] -> Accessibility -> FnOpts -> Name -> FC -> [PTerm] -> [(Name, PTerm)] -> PTerm -> Maybe Name -> [PDecl] -> Idris ()
- Idris.IBC: instance Data.Binary.Class.Binary Idris.AbsSyntaxTree.ClassInfo
- Idris.Parser: classBlock :: SyntaxInfo -> IdrisParser (Maybe (Name, FC), Docstring (Either Err PTerm), [PDecl])
- Idris.Parser: class_ :: SyntaxInfo -> IdrisParser [PDecl]
- Idris.Parser: instanceBlock :: SyntaxInfo -> IdrisParser [PDecl]
- Idris.Parser: instance_ :: Bool -> SyntaxInfo -> IdrisParser [PDecl]
- Idris.REPL: getClient :: Opt -> Maybe String
- Idris.REPL: getIBCSubDir :: Opt -> Maybe String
- Idris.REPL: getPkg :: Opt -> Maybe (Bool, String)
- Idris.REPL: getPkgCheck :: Opt -> Maybe String
- Idris.REPL: getPkgClean :: Opt -> Maybe String
- Idris.REPL: getPkgMkDoc :: Opt -> Maybe String
- Idris.REPL: getPkgREPL :: Opt -> Maybe String
- Idris.REPL: getPkgTest :: Opt -> Maybe String
- Idris.REPL: getPort :: [Opt] -> PortID
- Idris.REPL: idris :: [Opt] -> IO (Maybe IState)
- Idris.REPL: idrisMain :: [Opt] -> Idris ()
- Idris.REPL: loadInputs :: [FilePath] -> Maybe Int -> Idris [FilePath]
- Idris.REPL: opt :: (Opt -> Maybe a) -> [Opt] -> [a]
- Idris.REPL: runMain :: Idris () -> IO ()
- Idris.REPL: ver :: [Char]
+ Idris.ASTUtils: known_interfaces :: Field IState (Ctxt InterfaceInfo)
+ Idris.AbsSyntax: addImplementation :: Bool -> Bool -> Name -> Name -> Idris ()
+ Idris.AbsSyntax: addInterface :: Name -> InterfaceInfo -> Idris ()
+ Idris.AbsSyntax: addSourceDir :: FilePath -> Idris ()
+ Idris.AbsSyntax: allSourceDirs :: Idris [FilePath]
+ Idris.AbsSyntax: expandImplementationScope :: t -> t1 -> [(Name, t3)] -> t2 -> PDecl' t3 -> PDecl' t3
+ Idris.AbsSyntax: getBC :: Opt -> Maybe String
+ Idris.AbsSyntax: getCPU :: Opt -> Maybe String
+ Idris.AbsSyntax: getClient :: Opt -> Maybe String
+ Idris.AbsSyntax: getCodegen :: Opt -> Maybe Codegen
+ Idris.AbsSyntax: getCodegenArgs :: Opt -> Maybe String
+ Idris.AbsSyntax: getColour :: Opt -> Maybe Bool
+ Idris.AbsSyntax: getConsoleWidth :: Opt -> Maybe ConsoleWidth
+ Idris.AbsSyntax: getEvalExpr :: Opt -> Maybe String
+ Idris.AbsSyntax: getExecScript :: Opt -> Maybe String
+ Idris.AbsSyntax: getFile :: Opt -> Maybe String
+ Idris.AbsSyntax: getIBCSubDir :: Opt -> Maybe String
+ Idris.AbsSyntax: getImportDir :: Opt -> Maybe String
+ Idris.AbsSyntax: getLanguageExt :: Opt -> Maybe LanguageExt
+ Idris.AbsSyntax: getOptLevel :: Opt -> Maybe Int
+ Idris.AbsSyntax: getOptimisation :: Opt -> Maybe (Bool, Optimisation)
+ Idris.AbsSyntax: getOutput :: Opt -> Maybe String
+ Idris.AbsSyntax: getOutputTy :: Opt -> Maybe OutputType
+ Idris.AbsSyntax: getPkg :: Opt -> Maybe (Bool, String)
+ Idris.AbsSyntax: getPkgCheck :: Opt -> Maybe String
+ Idris.AbsSyntax: getPkgClean :: Opt -> Maybe String
+ Idris.AbsSyntax: getPkgDir :: Opt -> Maybe String
+ Idris.AbsSyntax: getPkgIndex :: Opt -> Maybe FilePath
+ Idris.AbsSyntax: getPkgMkDoc :: Opt -> Maybe String
+ Idris.AbsSyntax: getPkgREPL :: Opt -> Maybe String
+ Idris.AbsSyntax: getPkgTest :: Opt -> Maybe String
+ Idris.AbsSyntax: getPort :: [Opt] -> Maybe REPLPort
+ Idris.AbsSyntax: getSourceDir :: Opt -> Maybe String
+ Idris.AbsSyntax: getTriple :: Opt -> Maybe String
+ Idris.AbsSyntax: opt :: (Opt -> Maybe a) -> [Opt] -> [a]
+ Idris.AbsSyntax: setSourceDirs :: [FilePath] -> Idris ()
+ Idris.AbsSyntaxTree: DontListen :: REPLPort
+ Idris.AbsSyntaxTree: IBCImplementation :: Bool -> Bool -> Name -> Name -> IBCWrite
+ Idris.AbsSyntaxTree: IBCInterface :: Name -> IBCWrite
+ Idris.AbsSyntaxTree: IBCSourceDir :: FilePath -> IBCWrite
+ Idris.AbsSyntaxTree: ListenPort :: PortNumber -> REPLPort
+ Idris.AbsSyntaxTree: PImplementation :: (Docstring (Either Err t)) -> [(Name, Docstring (Either Err t))] -> SyntaxInfo -> FC -> [(Name, t)] -> [Name] -> Accessibility -> FnOpts -> Name -> FC -> [t] -> [(Name, t)] -> t -> (Maybe Name) -> [PDecl' t] -> PDecl' t
+ Idris.AbsSyntaxTree: PInterface :: (Docstring (Either Err t)) -> SyntaxInfo -> FC -> [(Name, t)] -> Name -> FC -> [(Name, FC, t)] -> [(Name, Docstring (Either Err t))] -> [(Name, FC)] -> [PDecl' t] -> (Maybe (Name, FC)) -> (Docstring (Either Err t)) -> PDecl' t
+ Idris.AbsSyntaxTree: RAddImplementation :: Name -> Name -> RDeclInstructions
+ Idris.AbsSyntaxTree: ShowAll :: Opt
+ Idris.AbsSyntaxTree: SourceDir :: String -> Opt
+ Idris.AbsSyntaxTree: StaticFn :: FnOpt
+ Idris.AbsSyntaxTree: TCImplementation :: PTactic' t
+ Idris.AbsSyntaxTree: [idris_interfaces] :: IState -> Ctxt InterfaceInfo
+ Idris.AbsSyntaxTree: [implementationCtorName] :: InterfaceInfo -> Name
+ Idris.AbsSyntaxTree: [interface_default_super_interfaces] :: InterfaceInfo -> [PDecl]
+ Idris.AbsSyntaxTree: [interface_defaults] :: InterfaceInfo -> [(Name, (Name, PDecl))]
+ Idris.AbsSyntaxTree: [interface_determiners] :: InterfaceInfo -> [Int]
+ Idris.AbsSyntaxTree: [interface_implementations] :: InterfaceInfo -> [(Name, Bool)]
+ Idris.AbsSyntaxTree: [interface_methods] :: InterfaceInfo -> [(Name, (Bool, FnOpts, PTerm))]
+ Idris.AbsSyntaxTree: [interface_params] :: InterfaceInfo -> [Name]
+ Idris.AbsSyntaxTree: [opt_sourcedirs] :: IOption -> [FilePath]
+ Idris.AbsSyntaxTree: data InterfaceInfo
+ Idris.AbsSyntaxTree: data REPLPort
+ Idris.AbsSyntaxTree: instance GHC.Classes.Eq Idris.AbsSyntaxTree.REPLPort
+ Idris.AbsSyntaxTree: instance GHC.Generics.Generic Idris.AbsSyntaxTree.InterfaceInfo
+ Idris.AbsSyntaxTree: instance GHC.Generics.Generic Idris.AbsSyntaxTree.REPLPort
+ Idris.AbsSyntaxTree: instance GHC.Show.Show Idris.AbsSyntaxTree.InterfaceInfo
+ Idris.AbsSyntaxTree: instance GHC.Show.Show Idris.AbsSyntaxTree.REPLPort
+ Idris.CmdOptions: getClient :: Opt -> Maybe String
+ Idris.CmdOptions: getIBCSubDir :: Opt -> Maybe String
+ Idris.CmdOptions: getPkg :: Opt -> Maybe (Bool, String)
+ Idris.CmdOptions: getPkgCheck :: Opt -> Maybe String
+ Idris.CmdOptions: getPkgClean :: Opt -> Maybe String
+ Idris.CmdOptions: getPkgMkDoc :: Opt -> Maybe String
+ Idris.CmdOptions: getPkgREPL :: Opt -> Maybe String
+ Idris.CmdOptions: getPkgTest :: Opt -> Maybe String
+ Idris.CmdOptions: getPort :: [Opt] -> Maybe REPLPort
+ Idris.CmdOptions: opt :: (Opt -> Maybe a) -> [Opt] -> [a]
+ Idris.Completion: instance GHC.Classes.Eq Idris.Completion.CompletionMode
+ Idris.Core.Elaborate: get_implementations :: Elab' aux [Name]
+ Idris.Core.Elaborate: implementationArg :: Name -> Elab' aux ()
+ Idris.Core.ProofState: Implementation :: Name -> Tactic
+ Idris.Core.ProofState: [implementations] :: ProofState -> [Name]
+ Idris.Core.TT: ImplementationCtorN :: !Name -> SpecialName
+ Idris.Core.TT: ImplementationN :: !Name -> [Text] -> SpecialName
+ Idris.Core.TT: [tcimplementation] :: ImplicitInfo -> Bool
+ Idris.Core.TT: pprintTTClause :: [(Name, Type)] -> Term -> Term -> Doc OutputAnnotation
+ Idris.Core.TT: sImplementationN :: Name -> [String] -> SpecialName
+ Idris.DeepSeq: instance Control.DeepSeq.NFData Idris.AbsSyntaxTree.InterfaceInfo
+ Idris.DeepSeq: instance Control.DeepSeq.NFData Idris.AbsSyntaxTree.REPLPort
+ Idris.DeepSeq: instance Control.DeepSeq.NFData Network.Socket.Types.PortNumber
+ Idris.Docs: InterfaceDoc :: Name -> d -> [FunDoc' d] -> [(Name, Maybe d)] -> [(Maybe Name, PTerm, (d, [(Name, d)]))] -> [PTerm] -> [PTerm] -> (Maybe (FunDoc' d)) -> Docs' d
+ Idris.Docs: NamedImplementationDoc :: Name -> (FunDoc' d) -> Docs' d
+ Idris.Elab.Implementation: elabImplementation :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> [(Name, Docstring (Either Err PTerm))] -> ElabWhat -> FC -> [(Name, PTerm)] -> [Name] -> Accessibility -> FnOpts -> Name -> FC -> [PTerm] -> [(Name, PTerm)] -> PTerm -> Maybe Name -> [PDecl] -> Idris ()
+ Idris.Elab.Interface: elabInterface :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> FC -> [(Name, PTerm)] -> Name -> FC -> [(Name, FC, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [(Name, FC)] -> [PDecl] -> Maybe (Name, FC) -> Docstring (Either Err PTerm) -> Idris ()
+ Idris.Elab.Interface: instance GHC.Show.Show Idris.Elab.Interface.MArgTy
+ Idris.IBC: instance Data.Binary.Class.Binary Idris.AbsSyntaxTree.InterfaceInfo
+ Idris.Info: getIdrisCC :: IO String
+ Idris.Info: getIdrisFlagsEnv :: IO [String]
+ Idris.Info: getIdrisFlagsInc :: IO [String]
+ Idris.Info: getIdrisFlagsLib :: IO [String]
+ Idris.Info: getIdrisHistoryFile :: IO FilePath
+ Idris.Info: getIdrisInitScript :: IO FilePath
+ Idris.Info: getIdrisInstalledPackages :: IO [String]
+ Idris.Info: getIdrisLibDir :: IO String
+ Idris.Info: getIdrisLoggingCategories :: IO [String]
+ Idris.Info: getIdrisUserDataDir :: IO FilePath
+ Idris.Info: getIdrisVersion :: [Char]
+ Idris.Info: getIdrisVersionNoGit :: Version
+ Idris.Info.Show: showExitIdrisFlagsInc :: IO ()
+ Idris.Info.Show: showExitIdrisFlagsLibs :: IO ()
+ Idris.Info.Show: showExitIdrisInfo :: IO ()
+ Idris.Info.Show: showExitIdrisInstalledPackages :: IO ()
+ Idris.Info.Show: showExitIdrisLibDir :: IO ()
+ Idris.Info.Show: showExitIdrisLoggingCategories :: IO ()
+ Idris.Info.Show: showIdrisFlagsInc :: IO ()
+ Idris.Info.Show: showIdrisFlagsLibs :: IO ()
+ Idris.Info.Show: showIdrisInfo :: IO ()
+ Idris.Info.Show: showIdrisInstalledPackages :: IO ()
+ Idris.Info.Show: showIdrisLibDir :: IO ()
+ Idris.Info.Show: showIdrisLoggingCategories :: IO ()
+ Idris.Main: idris :: [Opt] -> IO (Maybe IState)
+ Idris.Main: idrisMain :: [Opt] -> Idris ()
+ Idris.Main: loadInputs :: [FilePath] -> Maybe Int -> Idris [FilePath]
+ Idris.Main: runClient :: Maybe PortNumber -> String -> IO ()
+ Idris.Main: runMain :: Idris () -> IO ()
+ Idris.ModeCommon: banner :: [Char]
+ Idris.ModeCommon: defaultPort :: PortNumber
+ Idris.ModeCommon: loadInputs :: [FilePath] -> Maybe Int -> Idris [FilePath]
+ Idris.ModeCommon: warranty :: [Char]
+ Idris.Parser: implementation :: Bool -> SyntaxInfo -> IdrisParser [PDecl]
+ Idris.Parser: implementationBlock :: SyntaxInfo -> IdrisParser [PDecl]
+ Idris.Parser: interfaceBlock :: SyntaxInfo -> IdrisParser (Maybe (Name, FC), Docstring (Either Err PTerm), [PDecl])
+ Idris.Parser: interface_ :: SyntaxInfo -> IdrisParser [PDecl]
+ Idris.Parser.Ops: checkDeclFixity :: IdrisParser PDecl -> IdrisParser PDecl
+ Idris.Parser.Ops: checkNameFixity :: Name -> IdrisParser ()
+ Idris.REPL: idemodeStart :: Bool -> IState -> [FilePath] -> Idris ()
+ Idris.REPL: process :: FilePath -> Command -> Idris ()
+ Idris.REPL: proofs :: IState -> Idris ()
+ Idris.REPL: repl :: IState -> [FilePath] -> FilePath -> InputT Idris ()
+ Idris.REPL: replSettings :: Maybe FilePath -> Settings Idris
+ Idris.REPL: startServer :: PortNumber -> IState -> [FilePath] -> Idris ()
+ Idris.REPL.Commands: AddClauseFrom :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: AddMissing :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: AddProof :: (Maybe Name) -> Command
+ Idris.REPL.Commands: AddProofClauseFrom :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: Apropos :: [String] -> String -> Command
+ Idris.REPL.Commands: Browse :: [String] -> Command
+ Idris.REPL.Commands: CallsWho :: Name -> Command
+ Idris.REPL.Commands: CaseSplitAt :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: ChangeDirectory :: FilePath -> Command
+ Idris.REPL.Commands: Check :: PTerm -> Command
+ Idris.REPL.Commands: ColourOff :: Command
+ Idris.REPL.Commands: ColourOn :: Command
+ Idris.REPL.Commands: Compile :: Codegen -> String -> Command
+ Idris.REPL.Commands: Core :: PTerm -> Command
+ Idris.REPL.Commands: DebugInfo :: Name -> Command
+ Idris.REPL.Commands: DebugUnify :: PTerm -> PTerm -> Command
+ Idris.REPL.Commands: Defn :: Name -> Command
+ Idris.REPL.Commands: DoProofSearch :: Bool -> Bool -> Int -> Name -> [Name] -> Command
+ Idris.REPL.Commands: DocStr :: (Either Name Const) -> HowMuchDocs -> Command
+ Idris.REPL.Commands: DynamicLink :: FilePath -> Command
+ Idris.REPL.Commands: Edit :: Command
+ Idris.REPL.Commands: Eval :: PTerm -> Command
+ Idris.REPL.Commands: ExecVal :: PTerm -> Command
+ Idris.REPL.Commands: Execute :: PTerm -> Command
+ Idris.REPL.Commands: Help :: Command
+ Idris.REPL.Commands: ListDynamic :: Command
+ Idris.REPL.Commands: ListErrorHandlers :: Command
+ Idris.REPL.Commands: Load :: FilePath -> (Maybe Int) -> Command
+ Idris.REPL.Commands: LogCategory :: [LogCat] -> Command
+ Idris.REPL.Commands: LogLvl :: Int -> Command
+ Idris.REPL.Commands: MakeCase :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: MakeDoc :: String -> Command
+ Idris.REPL.Commands: MakeLemma :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: MakeWith :: Bool -> Int -> Name -> Command
+ Idris.REPL.Commands: Metavars :: Command
+ Idris.REPL.Commands: Missing :: Name -> Command
+ Idris.REPL.Commands: ModImport :: String -> Command
+ Idris.REPL.Commands: NOP :: Command
+ Idris.REPL.Commands: NewDefn :: [PDecl] -> Command
+ Idris.REPL.Commands: PPrint :: OutputFmt -> Int -> PTerm -> Command
+ Idris.REPL.Commands: Pattelab :: PTerm -> Command
+ Idris.REPL.Commands: PrintDef :: Name -> Command
+ Idris.REPL.Commands: Proofs :: Command
+ Idris.REPL.Commands: Prove :: Bool -> Name -> Command
+ Idris.REPL.Commands: Quit :: Command
+ Idris.REPL.Commands: Reload :: Command
+ Idris.REPL.Commands: RmProof :: Name -> Command
+ Idris.REPL.Commands: Search :: [String] -> PTerm -> Command
+ Idris.REPL.Commands: SetColour :: ColourType -> IdrisColour -> Command
+ Idris.REPL.Commands: SetConsoleWidth :: ConsoleWidth -> Command
+ Idris.REPL.Commands: SetOpt :: Opt -> Command
+ Idris.REPL.Commands: SetPrinterDepth :: (Maybe Int) -> Command
+ Idris.REPL.Commands: ShowProof :: Name -> Command
+ Idris.REPL.Commands: Spec :: PTerm -> Command
+ Idris.REPL.Commands: TestInline :: PTerm -> Command
+ Idris.REPL.Commands: TotCheck :: Name -> Command
+ Idris.REPL.Commands: TransformInfo :: Name -> Command
+ Idris.REPL.Commands: Undefine :: [Name] -> Command
+ Idris.REPL.Commands: Universes :: Command
+ Idris.REPL.Commands: UnsetOpt :: Opt -> Command
+ Idris.REPL.Commands: WHNF :: PTerm -> Command
+ Idris.REPL.Commands: Warranty :: Command
+ Idris.REPL.Commands: Watch :: Command
+ Idris.REPL.Commands: WhoCalls :: Name -> Command
+ Idris.REPL.Commands: data Command
- Idris.AbsSyntaxTree: CI :: Name -> [(Name, (Bool, FnOpts, PTerm))] -> [(Name, (Name, PDecl))] -> [PDecl] -> [Name] -> [(Name, Bool)] -> [Int] -> ClassInfo
+ Idris.AbsSyntaxTree: CI :: Name -> [(Name, (Bool, FnOpts, PTerm))] -> [(Name, (Name, PDecl))] -> [PDecl] -> [Name] -> [(Name, Bool)] -> [Int] -> InterfaceInfo
- Idris.AbsSyntaxTree: DSL :: t -> t -> t -> t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> DSL' t
+ Idris.AbsSyntaxTree: DSL :: t -> t -> t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> Maybe t -> DSL' t
- Idris.AbsSyntaxTree: IOption :: Int -> [LogCat] -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Codegen -> OutputType -> FilePath -> [FilePath] -> String -> String -> [Opt] -> Bool -> Bool -> [FilePath] -> [Optimisation] -> Maybe Int -> Bool -> Bool -> Bool -> IOption
+ Idris.AbsSyntaxTree: IOption :: Int -> [LogCat] -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Codegen -> OutputType -> FilePath -> [FilePath] -> [FilePath] -> String -> String -> [Opt] -> Bool -> Bool -> [FilePath] -> [Optimisation] -> Maybe Int -> Bool -> Bool -> Bool -> IOption
- Idris.AbsSyntaxTree: IState :: Context -> Set ConstraintFC -> [FixDecl] -> Ctxt [PArg] -> Ctxt [Bool] -> Ctxt ClassInfo -> [Name] -> Ctxt RecordInfo -> Ctxt DSL -> Ctxt OptInfo -> Ctxt TypeInfo -> Ctxt [Name] -> Ctxt ([([(Name, Term)], Term, Term)], [PTerm]) -> Ctxt [FnOpt] -> Ctxt CGInfo -> Ctxt (Docstring DocTerm, [(Name, Docstring DocTerm)]) -> Ctxt (Docstring DocTerm) -> Ctxt TIData -> Ctxt FnInfo -> Ctxt [(Term, Term)] -> Ctxt [Name] -> [(FC, Name)] -> [(FC, Name)] -> [(FC, String)] -> IOption -> Int -> [((FilePath, Int), PTerm)] -> [(Name, (Maybe Name, Int, [Name], Bool, Bool))] -> [Name] -> [(Term, Term)] -> SyntaxRules -> [String] -> [FilePath] -> [(Name, (Int, PrimFn))] -> [(Codegen, FilePath)] -> [(Codegen, String)] -> [(Codegen, String)] -> [(Codegen, String)] -> [(FilePath, Bool)] -> [(Name, (Bool, [String]))] -> Maybe FC -> [(FC, Err)] -> Maybe Name -> [Int] -> [Maybe Int] -> Maybe FC -> Maybe FC -> Ctxt Accessibility -> Accessibility -> DefaultTotality -> [IBCWrite] -> Maybe String -> [DynamicLib] -> [LanguageExt] -> OutputMode -> Bool -> ColourTheme -> [Name] -> (Int, Ctxt (Int, Name)) -> Ctxt (Map Name (Set Name)) -> Map [Text] [Text] -> ConsoleWidth -> Set Name -> Set (Name, Int) -> [(Name, Int)] -> Maybe (Map Name [Name]) -> Maybe (Map Name [Name]) -> [Name] -> [(Name, Bool)] -> Map Name Name -> [Name] -> [(FC, OutputAnnotation)] -> [(FC, OutputAnnotation)] -> Ctxt String -> Set Name -> Map Term (Int, Term) -> Ctxt String -> IState
+ Idris.AbsSyntaxTree: IState :: Context -> Set ConstraintFC -> [FixDecl] -> Ctxt [PArg] -> Ctxt [Bool] -> Ctxt InterfaceInfo -> [Name] -> Ctxt RecordInfo -> Ctxt DSL -> Ctxt OptInfo -> Ctxt TypeInfo -> Ctxt [Name] -> Ctxt ([([(Name, Term)], Term, Term)], [PTerm]) -> Ctxt [FnOpt] -> Ctxt CGInfo -> Ctxt (Docstring DocTerm, [(Name, Docstring DocTerm)]) -> Ctxt (Docstring DocTerm) -> Ctxt TIData -> Ctxt FnInfo -> Ctxt [(Term, Term)] -> Ctxt [Name] -> [(FC, Name)] -> [(FC, Name)] -> [(FC, String)] -> IOption -> Int -> [((FilePath, Int), PTerm)] -> [(Name, (Maybe Name, Int, [Name], Bool, Bool))] -> [Name] -> [(Term, Term)] -> SyntaxRules -> [String] -> [FilePath] -> [(Name, (Int, PrimFn))] -> [(Codegen, FilePath)] -> [(Codegen, String)] -> [(Codegen, String)] -> [(Codegen, String)] -> [(FilePath, Bool)] -> [(Name, (Bool, [String]))] -> Maybe FC -> [(FC, Err)] -> Maybe Name -> [Int] -> [Maybe Int] -> Maybe FC -> Maybe FC -> Ctxt Accessibility -> Accessibility -> DefaultTotality -> [IBCWrite] -> Maybe String -> [DynamicLib] -> [LanguageExt] -> OutputMode -> Bool -> ColourTheme -> [Name] -> (Int, Ctxt (Int, Name)) -> Ctxt (Map Name (Set Name)) -> Map [Text] [Text] -> ConsoleWidth -> Set Name -> Set (Name, Int) -> [(Name, Int)] -> Maybe (Map Name [Name]) -> Maybe (Map Name [Name]) -> [Name] -> [(Name, Bool)] -> Map Name Name -> [Name] -> [(FC, OutputAnnotation)] -> [(FC, OutputAnnotation)] -> Ctxt String -> Set Name -> Map Term (Int, Term) -> Ctxt String -> IState
- Idris.AbsSyntaxTree: PUniverse :: Universe -> PTerm
+ Idris.AbsSyntaxTree: PUniverse :: FC -> Universe -> PTerm
- Idris.AbsSyntaxTree: Port :: String -> Opt
+ Idris.AbsSyntaxTree: Port :: REPLPort -> Opt
- Idris.CmdOptions: preProcOpts :: [Opt] -> [Opt] -> [Opt]
+ Idris.CmdOptions: preProcOpts :: [Opt] -> [Opt]
- Idris.REPL: runClient :: PortID -> String -> IO ()
+ Idris.REPL: runClient :: Maybe PortNumber -> String -> IO ()

Files

+ .gitattributes view
@@ -0,0 +1,1 @@+* text=auto
+ .gitignore view
@@ -0,0 +1,54 @@+# Build artefacts+dist+*.ibc+*.o+*.a+*.so+*.dll+*.dylib+src/Version_idris.hs++# Doc generation artefacts+libs/base/base_doc/+libs/effects/effects_doc/+libs/prelude/prelude_doc/+libs/contrib/contrib_doc/+libs/pruviloj/pruviloj_doc/+libs/oldeffects/oldeffects_doc/++# Test artefacts+test/output+test/*[0-9][0-9][0-9]/output+test/*[0-9][0-9][0-9]/*.exe+test/runtest.exe+test/runtest+.tasty-rerun-log++# Haskell build tools+cabal-dev/+.cabal-sandbox+cabal.sandbox.config+cabal.config+.stack-work+.hsenv++# For convenience+custom.mk+\#*+.\#*+tags+TAGS++# IDE and editors+*.swp+*~+.DS_Store+.hpc+*.orig+*.tix+*.dSYM+.projectile+.dir-locals.el+.vscode+.idea+
+ .travis.yml view
@@ -0,0 +1,149 @@+sudo: false++language: c++env:+  global:+    - PKGNAME=idris++matrix:+  include:+    - os: osx+      env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"+      compiler: ": #GHC 8.0.1"+    - env: CABALVER="1.20" GHCVER="7.6.3" TESTS="test_c"+      # separate caches for different compiler versions+      # until https://github.com/travis-ci/travis-ci/issues/4393 is resolved+      compiler: ": #GHC 7.6.3"+      addons: {apt: {packages: [cabal-install-1.20,ghc-7.6.3,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.20" GHCVER="7.8.4" TESTS="test_c"+      compiler: ": #GHC 7.8.4"+      addons: {apt: {packages: [cabal-install-1.20,ghc-7.8.4,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="lib_doc doc"+      compiler: ": #GHC 7.10.3"+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="test_js"+      compiler: ": #GHC 7.10.3"+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="test_c"+      compiler: ": #GHC 7.10.3"+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="lib_doc doc"+      compiler: ": #GHC 8.0.1"+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_js"+      compiler: ": #GHC 8.0.1"+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}+    - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"+      compiler: ": #GHC 8.0.1"+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}++cache:+  directories:+    - $HOME/.cabsnap+    - $HOME/.cabal/packages++before_cache:+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar++before_install:+  - unset CC+  - if [[ $TRAVIS_OS_NAME == 'linux' ]];+    then+        export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH;+        export SED=sed;+        export ZCAT=zcat;+    fi+  - env+  - if [[ $TRAVIS_OS_NAME == 'osx' ]];+    then+        brew update; brew install ghc; brew install cabal-install;+        brew install libffi; brew install pkg-config; brew install cppcheck;+        brew install gnu-sed;+        export PATH=$HOME/.cabal/bin:$PATH;+        export SED=gsed;+        export ZCAT=gzcat;+        export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH;+    fi++install:+  - cabal --version+  - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"+  - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];+    then+      $ZCAT $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >+              $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;+    fi+  - travis_retry cabal update -v+  # Run build with 2 parallel jobs+  # The container environment reports 16 cores,+  # causing cabal's default configuration (jobs: $ncpus)+  # to run into the GHC #9221 bug which can result in longer build-times.+  - $SED -i -r 's/(^jobs:).*/\1 2/' $HOME/.cabal/config+  - cabal install -f FFI --only-dependencies --enable-tests --dry -v > installplan.txt+  - $SED -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt+  # check whether current requested install-plan matches cached package-db snapshot+  - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;+    then+      echo "cabal build-cache HIT";+      rm -rfv .ghc;+      cp -a $HOME/.cabsnap/ghc $HOME/.ghc;+      cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;+    else+      echo "cabal build-cache MISS";+      rm -rf $HOME/.cabsnap;+      mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;+      cabal install -f FFI --only-dependencies --enable-tests;+    fi+  # snapshot package-db on cache miss+  - if [ ! -d $HOME/.cabsnap ];+    then+      echo "snapshotting package-db to build-cache";+      mkdir $HOME/.cabsnap;+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;+    fi++before_script:+  - ORIGINAL_DIR=$(pwd)+  - cabal sdist+  - cd ..+  - tar -xf ${ORIGINAL_DIR}/dist/${PKGNAME}*.tar.gz+  - cd ${PKGNAME}*+script:+###+  - echo 'Configure...' && echo -en 'travis_fold:start:script.configure\\r'+  - cabal configure -f FFI -f CI --enable-tests+  - echo -en 'travis_fold:end:script.configure\\r'+###+  - echo 'Build...' && echo -en 'travis_fold:start:script.build\\r'+  - cabal build+  - echo -en 'travis_fold:end:script.build\\r'+###+  - echo 'Copy...' && echo -en 'travis_fold:start:script.copy\\r'+  - cabal copy+  - echo -en 'travis_fold:end:script.copy\\r'+###+  - echo 'Register...' && echo -en 'travis_fold:start:script.register\\r'+  - cabal register+  - echo -en 'travis_fold:end:script.register\\r'+###+  - echo 'Cppcheck...' && echo -en 'travis_fold:start:script.cppcheck\\r'+  - if [[ "$TESTS" == "test_c" ]]; then+      cppcheck -i 'mini-gmp.c' rts;+    fi+  - echo -en 'travis_fold:end:script.cppcheck\\r'+###+  - echo 'Tests...' && echo -en 'travis_fold:start:script.tests\\r'+  - for test in $TESTS; do+      echo "make TEST-JOBS=2 $test";+      travis_wait make TEST-JOBS=2 $test;+    done+  - echo -en 'travis_fold:end:script.tests\\r'+###+  - echo 'Benchmarks...' && echo -en 'travis_fold:start:script.benchmarks\\r'+  - cd benchmarks && ./build.pl && ./run.pl && cd ..+  - echo -en 'travis_fold:end:script.benchmarks\\r'+###+# EOF
CHANGELOG.md view
@@ -26,16 +26,33 @@ * The File Effect has been updated to take into account changes in   `Prelude.File` and to provide a 'better' API. * `natEnumFromThen` and `natEnumFromTo` have been updated to correctly calculate reverse ranges. Range syntax `[a,b..c]` now can be used again to generate reverse ranges.+* `divBN` and `modBN` now can only be used for unsigned numbers.+* `return`, which has been an alias for `pure` for many releases, is now deprecated.+* Replace instance with implementation:+  + `InstanceN` is deprecated, use `ImplementationN` instead.+  + `InstanceCtorN` is deprecated, use `ImplementationCtorN` instead.+  + `addInstance` is deprecated, use `addImplementation` instead.+  + `%instance` keyword is deprecated, use `%implementation` instead. +* Idris packages are now installed within a sub-directory `libs` of Idris' data directory, before they were installed in the directory's root.+ ## Tool updates  * Idris' documentation system now displays the documentation for auto   implicits in the output of `:doc`. This is tested for in `docs005`. +* New command line flag `--info` that displays information about the installation.++* New command line flag `--sourcepath <dir>` that allows adding directories to the source search path. ## Miscellaneous updates  * The test suite now uses [tasty-golden](https://hackage.haskell.org/package/tasty-golden). New tests must be registered in `test/TestData.hs`, as explained in the relevant `README.md`. * Added OSX and Windows continous integration with Travis and Appveyor.++## UI Changes++* The :e command can now handle an $EDITOR with arguments in it, like "emacs -nw" +  # New in 0.12: 
CONTRIBUTORS view
@@ -7,6 +7,7 @@ Jan Bessai Nicola Botta Edwin Brady+Vitaly Bragilevsky Jakob Brünker Alyssa Carter Carter Charbonneau@@ -51,3 +52,5 @@ Daniel Waterworth Eric Weinstein Jonas Westerlund+Björn Aili+Zheng Jihui
+ INSTALL.md view
@@ -0,0 +1,104 @@+# Idris Installation Guide++Copyright (C) 2015, The Idris Community++## Installing Idris from Hackage++This repository represents the latest development version of the+language, and may contain bugs that are being actively worked on.  For+those who wish to use a more stable version of Idris please consider+installing the latest version that has been released on Hackage.+Installation instructions for various platforms can be+[found on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installation-Instructions).++## Installing Development Versions++If you like to work against the latest development version, please+consider using Cabal Sandboxes to minimise disruption to your local+Haskell setup.  Instructions for installing Idris HEAD within a cabal+sandbox are+[available on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installing-an-Idris-Development-version-in-a-sandbox).++To configure, edit config.mk. The default values should work for most+people.++Idris is built using a Makefile common targets include:++* `make` This will install everything using cabal and typecheck the+  libraries.+* `make test` This target execute the test suite.+* `make relib` This target will typecheck and recompile the standard+  library.++Idris has an optional dependency on the `C` library `libffi`. If you+would like to use the features that it enables, make sure that it is+compiled for the same architecture as your Haskell compiler (e.g. 64+bit libraries for 64 bit ghc). By default, Idris builds without it. To+build with it, pass the flag `-f FFI`.++A secondary optional dependency is on `libGMP`, this allows better+support for numeric operations. As with `libFFI` Idris builds with out+it, to enable `GMP` support use the flag `-f GMP`++To build with `libffi` and `libGMP` by default, create a `custom.mk`+file and add the following line to it:++`CABALFLAGS += -f FFI -f GMP`++The file `custom.mk-alldeps` is a suitable example.++The continuous integration builds on travis-ci.org are built using the+ghc-flag -Werror. To enable this behaviour locally also, please+compile using `make CI=true` or adding the following line into+`custom.mk`:++`CI = true`++If you are only compiling for installing the most current version, you+can omit the CI flag, but please make sure you use it if you want to+contribute.++## Experimental Support for Building with Stack++[Stack](https://github.com/commercialhaskell/stack) is a new+cross-platform program for developing Haskell projects, that enhances+the functionality provided by Cabal. There is experimental support for+building Idris from source with stack.+This installation has been tested on Ubuntu 16.04.1 LTS, and the current+NixOS unstable.++To build Idris with stack the following commands are recommended:++* `stack build`++This will install Idris (and related executables) into `./local/bin/`+on Unix based systems and an appropriate place on Windows. If you+haven't used stack before this will also setup the related+infrastructure. For more information about Stack please visit the+[Stack website](https://github.com/commercialhaskell/stack).++On NixOS, please use the following command instead, to make sure+the required libraries and header files are available:++* `stack build --nix`++### System GHC++The flag `--system-ghc` can be added to enforce use of your system's+version of GHC.++### `libGMP` and `libFFI`++By default the stack configuration in `stack.yaml` will build with+support for `libGMP` and `libFFI`.  To turn this support off, the+option flags needs to be fully commented out.++There have been reports in the past over building Idris on Mac OS X,+using stack, and linking to a HomeBrew installation of `libFFI`. The+build has failed to find the correct `libFFI` installation. If you+encounter this then the fix is to augment the `PKG_CONFIG_PATH` for+`libFFI`. For example:++```+PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig stack build+```
README.md view
@@ -4,7 +4,8 @@ [![Appveyor build](https://ci.appveyor.com/api/projects/status/xi8yu81oy1134g7o/branch/master?svg=true)](https://ci.appveyor.com/project/idrislang/idris-dev) [![Documentation Status](https://readthedocs.org/projects/idris/badge/?version=latest)](https://readthedocs.org/projects/idris/?badge=latest) [![Hackage](https://budueba.com/hackage/idris)](https://hackage.haskell.org/package/idris)-+[![Stackage LTS](http://stackage.org/package/idris/badge/lts)](http://stackage.org/lts/package/idris)+[![Stackage Nightly](http://stackage.org/package/idris/badge/nightly)](http://stackage.org/nightly/package/idris)  Idris (http://idris-lang.org/) is a general-purpose functional programming language with dependent types.
Setup.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+ import Control.Monad import Data.IORef import Control.Exception (SomeException, catch)@@ -80,6 +81,7 @@     Just True -> True     Just False -> False     Nothing -> False+ -- ----------------------------------------------------------------------------- -- Clean @@ -91,7 +93,6 @@        makeClean dir = make verbosity [ "-C", dir, "clean", "IDRIS=idris" ] - -- ----------------------------------------------------------------------------- -- Configure @@ -182,6 +183,17 @@   generateToolchainModule verb "src" Nothing   preSDist simpleUserHooks args flags +idrisSDist sdist pkgDesc bi hooks flags = do+  pkgDesc' <- addGitFiles pkgDesc+  sdist pkgDesc' bi hooks flags+    where+      addGitFiles :: PackageDescription -> IO PackageDescription+      addGitFiles pkgDesc = do+        files <- gitFiles+        return $ pkgDesc { extraSrcFiles = extraSrcFiles pkgDesc ++ files}+      gitFiles :: IO [FilePath]+      gitFiles = liftM lines (readProcess "git" ["ls-files"] "")+ idrisPostSDist args flags desc lbi = do   Control.Exception.catch (do let file = "src" </> "Version_idris" Px.<.> "hs"                               let targetFile = "src" </> "Target_idris" Px.<.> "hs"@@ -201,13 +213,11 @@       let buildinfo = (emptyBuildInfo { cppOptions = ["-DVERSION="++hash] }) :: BuildInfo       return (Just buildinfo, []) -- idrisPreBuild args flags = do #ifdef mingw32_HOST_OS         createDirectoryIfMissingVerbose verbosity True dir-        windres verbosity ["icons/idris_icon.rc","-o", dir++"idris_icon.o"]-        return (Nothing, [("idris", emptyBuildInfo { ldOptions = [dir ++ "idris_icon.o"] })])+        windres verbosity ["icons/idris_icon.rc","-o", dir++"/idris_icon.o"]+        return (Nothing, [("idris", emptyBuildInfo { ldOptions = [dir ++ "/idris_icon.o"] })])      where         verbosity = S.fromFlag $ S.buildVerbosity flags         dir = S.fromFlagOrDefault "dist" $ S.buildDistPref flags@@ -233,8 +243,6 @@       gmpflag False = []       gmpflag True = ["GMP=-DIDRIS_GMP"] -- -- ----------------------------------------------------------------------------- -- Copy/Install @@ -246,8 +254,9 @@       target = datadir $ L.absoluteInstallDirs pkg local copy        installStdLib = do-            putStrLn $ "Installing libraries in " ++ target-            makeInstall "libs" target+        let target' = target </> "libs"+        putStrLn $ "Installing libraries in " ++ target'+        makeInstall "libs" target'        installRTS = do          let target' = target </> "rts"@@ -304,6 +313,7 @@                   idrisInstall (S.fromFlag $ S.installVerbosity flags)                                NoCopyDest pkg local    , preSDist = idrisPreSDist+   , sDistHook = idrisSDist (sDistHook simpleUserHooks)    , postSDist = idrisPostSDist #if __GLASGOW_HASKELL__ < 710    , testHook = idrisTestHook ()
+ appveyor.yml view
@@ -0,0 +1,26 @@+version: 1.0.{build}+init:+- ps: >-+    choco install cabal++    mkdir C:\ghc++    Invoke-WebRequest "http://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-unknown-mingw32.tar.xz" -OutFile C:\ghc\ghc.tar.xz -UserAgent "Curl"+    +    7z x C:\ghc\ghc.tar.xz -oC:\ghc+    +    7z x C:\ghc\ghc.tar -oC:\ghc++    $env:PATH="$env:PATH;c:\ghc\ghc-7.10.3\bin;$HOME\AppData\Roaming\cabal\bin"++    cabal update++    $env:current_posix=c:\msys64\usr\bin\cygpath -u $(pwd)++environment:+  MSYSTEM: MINGW64+  MSYS2_PATH_TYPE: inherit+build_script:+- ps: c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && cabal install -fffi -j4 --enable-tests"+test_script:+- ps: c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && make test_c"
benchmarks/fasta/fasta.idr view
@@ -31,7 +31,7 @@ writeAlu : String -> String -> IO () writeAlu name s0 = putStrLn name *> go s0   where-    go "" = return ()+    go "" = pure ()     go s  = let (h,t) = splitAt' 60 s in putStrLn h *> go t  replicate : Int -> Char -> String@@ -64,7 +64,7 @@     lookupTable = Foldable.concat (fill (scanl accum ('a',0) tbl) 0)      make' : Int -> Int -> Int -> String -> IO Int-    make' 0 col seed buf = when (col > 0) (putStrLn buf) *> return seed+    make' 0 col seed buf = when (col > 0) (putStrLn buf) *> pure seed     make' n col seed buf = do       let newseed  = modInt (seed * 3877 + 29573) modulus       let nextchar = strIndex lookupTable newseed@@ -80,4 +80,4 @@     writeAlu ">ONE Homo sapiens alu" (takeRepeat (fromInteger (cast n)*2) alu)     nseed <- make ">TWO IUB ambiguity codes" (fromInteger (cast n)*3) iub 42     make ">THREE Homo sapiens frequency" (fromInteger (cast n)*5) homosapiens nseed-    return ()+    pure ()
benchmarks/pidigits/pidigits.idr view
@@ -46,7 +46,7 @@   let n = fromIntegerNat (the Integer (cast a))   let l = str (MkF 1 0 1) 1 n   loop 10 0 l-  return ()+  pure ()  main : IO () main = pidigit
benchmarks/quasigroups/Parser.idr view
@@ -14,24 +14,24 @@ Parser n = Either ParseErr (b : Board n ** LegalBoard b)  mapM : Monad m => (a -> m b) -> Vect n a -> m (Vect n b)-mapM _ Nil = return Vect.Nil+mapM _ Nil = pure Vect.Nil mapM f (x::xs) = do   x' <- f x   xs' <- mapM f xs-  return (Vect.(::) x' xs')+  pure (Vect.(::) x' xs')  parseToken : String -> Either String (Cell n)-parseToken "." = return Nothing+parseToken "." = pure Nothing parseToken "0" = Left "Got cell 0, expected 1-based numbering" parseToken x = map Just (tryParseFin ((cast x) - 1))   where     tryParseFin : Int -> Either String (Fin n)     tryParseFin {n=Z} _ = Left ("Given cell " ++ x ++ " out of range")-    tryParseFin {n=S k} 0 = return FZ+    tryParseFin {n=S k} 0 = pure FZ     tryParseFin {n=S k} x =       case tryParseFin {n=k} (x-1) of         Left err => Left err-        Right fin => return (FS fin)+        Right fin => pure (FS fin)  length : Vect n a -> Nat length {n=n} _ = n@@ -45,7 +45,7 @@       let here = (x, row) -- TODO: Determine why naming this makes idris smarter       tok <- parseToken {n=S k} (index x cs)       case tok of-        Nothing => return (_ ** l)+        Nothing => pure (_ ** l)         Just t =>            case legalVal b here t of              Yes prf => Right (_ ** Step prf l)@@ -79,4 +79,4 @@   let rows = fromList (lines str) in   case parseRows {n=length rows} emptyBoard Base rows of     Left msg => Left msg-    Right board => return (_ ** board)+    Right board => pure (_ ** board)
benchmarks/quasigroups/Solver.idr view
@@ -184,9 +184,8 @@   | Left full = Just (b ** (l, full))   | Right (coords ** p) = recurse last   where-    %assert_total     tryAll : (v : Fin (S n)) -> (Fin (S n), Maybe (b' : Board (S n) ** LegalBoard b'))-    tryAll v = --trace ("Trying " ++ show (the Int (cast v))) $+    tryAll v = assert_total $ --trace ("Trying " ++ show (the Int (cast v))) $       case tryValue l coords p v of         Right success => (v, Just success)         Left _ => -- TODO: Prove unsolvable@@ -194,9 +193,8 @@             FS k => tryAll (weaken k)             FZ => (v, Nothing) -    %assert_total     recurse : Fin (S n) -> Maybe (b' : Board (S n) ** CompleteBoard b')-    recurse start =+    recurse start = assert_total $       case tryAll start of         (_, Nothing) => Nothing         (FZ, Just (b' ** l')) => fillBoard b' l'
benchmarks/trivial/sortvec.idr view
@@ -15,8 +15,8 @@ vsort (x :: xs) = insert x (vsort xs)  mkSortVec : (n : Nat) -> Eff (Vect n Int) [RND]-mkSortVec Z = return []-mkSortVec (S k) = return (fromInteger !(rndInt 0 10000) :: !(mkSortVec k))+mkSortVec Z = pure []+mkSortVec (S k) = pure (fromInteger !(rndInt 0 10000) :: !(mkSortVec k))  main : IO () main = do (_ :: arg :: _) <- getArgs
codegen/idris-codegen-c/Main.hs view
@@ -3,8 +3,7 @@ import Idris.Core.TT import Idris.AbsSyntax import Idris.ElabDecls-import Idris.REPL-+import Idris.Main import IRTS.Compiler import IRTS.CodegenC 
codegen/idris-codegen-javascript/Main.hs view
@@ -3,8 +3,7 @@ import Idris.Core.TT import Idris.AbsSyntax import Idris.ElabDecls-import Idris.REPL-+import Idris.Main import IRTS.Compiler import IRTS.CodegenJavaScript 
codegen/idris-codegen-node/Main.hs view
@@ -3,7 +3,7 @@ import Idris.Core.TT import Idris.AbsSyntax import Idris.ElabDecls-import Idris.REPL+import Idris.Main  import IRTS.Compiler import IRTS.CodegenJavaScript
+ custom.mk-alldeps view
@@ -0,0 +1,1 @@+CABALFLAGS += -f GMP  -f FFI --disable-documentation --disable-profiling --disable-library-profiling
+ docs/.gitignore view
@@ -0,0 +1,3 @@+*~+UnicodeData.txt+_build/
+ docs/LICENSE view
@@ -0,0 +1,10 @@+#+TITLE: Licensing Information++The documentation for Idris has been published under the Creative+Commons CC0 License. As such to the extent possible under law, /The+Idris Community/ has waived all copyright and related or neighboring+rights to Documentation for Idris.++More information concerning the CC0 can be found online at:++    http://creativecommons.org/publicdomain/zero/1.0/
+ docs/Makefile view
@@ -0,0 +1,183 @@+# Makefile for Sphinx documentation+#++# You can set these variables from the command line.+SPHINXOPTS    =+SPHINXBUILD   = sphinx-build+PAPER         =+BUILDDIR      = _build++# User-friendly check for sphinx-build+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)+endif++# Internal variables.+PAPEROPT_a4     = -D latex_paper_size=a4+PAPEROPT_letter = -D latex_paper_size=letter+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .+# the i18n builder cannot share the environment and doctrees with the others+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .++.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext++help:+	@echo "Please use \`make <target>' where <target> is one of"+	@echo "  html       to make standalone HTML files"+	@echo "  dirhtml    to make HTML files named index.html in directories"+	@echo "  singlehtml to make a single large HTML file"+	@echo "  pickle     to make pickle files"+	@echo "  json       to make JSON files"+	@echo "  htmlhelp   to make HTML files and a HTML help project"+	@echo "  qthelp     to make HTML files and a qthelp project"+	@echo "  devhelp    to make HTML files and a Devhelp project"+	@echo "  epub       to make an epub"+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"+	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"+	@echo "  text       to make text files"+	@echo "  man        to make manual pages"+	@echo "  texinfo    to make Texinfo files"+	@echo "  info       to make Texinfo files and run them through makeinfo"+	@echo "  gettext    to make PO message catalogs"+	@echo "  changes    to make an overview of all changed/added/deprecated items"+	@echo "  xml        to make Docutils-native XML files"+	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"+	@echo "  linkcheck  to check all external links for integrity"+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"+	@echo "  coverage   to run coverage check of the documentation (if enabled)"++clean:+	rm -rf $(BUILDDIR)/*++html:+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html+	@echo+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."++dirhtml:+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml+	@echo+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."++singlehtml:+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml+	@echo+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."++pickle:+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle+	@echo+	@echo "Build finished; now you can process the pickle files."++json:+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json+	@echo+	@echo "Build finished; now you can process the JSON files."++htmlhelp:+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp+	@echo+	@echo "Build finished; now you can run HTML Help Workshop with the" \+	      ".hhp project file in $(BUILDDIR)/htmlhelp."++qthelp:+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp+	@echo+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/IdrisManual.qhcp"+	@echo "To view the help file:"+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/IdrisManual.qhc"++devhelp:+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp+	@echo+	@echo "Build finished."+	@echo "To view the help file:"+	@echo "# mkdir -p $$HOME/.local/share/devhelp/IdrisManual"+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/IdrisManual"+	@echo "# devhelp"++epub:+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub+	@echo+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."++latex:+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex+	@echo+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."+	@echo "Run \`make' in that directory to run these through (pdf)latex" \+	      "(use \`make latexpdf' here to do that automatically)."++latexpdf:+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex+	@echo "Running LaTeX files through pdflatex..."+	$(MAKE) -C $(BUILDDIR)/latex all-pdf+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."++latexpdfja:+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex+	@echo "Running LaTeX files through platex and dvipdfmx..."+	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."++text:+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text+	@echo+	@echo "Build finished. The text files are in $(BUILDDIR)/text."++man:+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man+	@echo+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."++texinfo:+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo+	@echo+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."+	@echo "Run \`make' in that directory to run these through makeinfo" \+	      "(use \`make info' here to do that automatically)."++info:+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo+	@echo "Running Texinfo files through makeinfo..."+	make -C $(BUILDDIR)/texinfo info+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."++gettext:+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale+	@echo+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."++changes:+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes+	@echo+	@echo "The overview file is in $(BUILDDIR)/changes."++linkcheck:+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck+	@echo+	@echo "Link check complete; look for any errors in the above output " \+	      "or in $(BUILDDIR)/linkcheck/output.txt."++doctest:+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest+	@echo "Testing of doctests in the sources finished, look at the " \+	      "results in $(BUILDDIR)/doctest/output.txt."++coverage:+	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage+	@echo "Testing of coverage in the sources finished, look at the " \+	      "results in $(BUILDDIR)/coverage/python.txt."++xml:+	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml+	@echo+	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."++pseudoxml:+	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml+	@echo+	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+ docs/README.md view
@@ -0,0 +1,51 @@+# Documentation for the Idris Language.+++This manual has been prepared using ReStructured Text and the [Sphinx Documentation Generator](http://sphinx-doc.org) for future inclusion on [Read The Docs](http://www.readthedocs.org).++## Dependencies++To build the manual the following dependencies must be met. We assume that you have standard build automation tools already install i.e. `make`.++### Sphinx-Doc++Python should be installed by default on most systems.+Sphinx can be installed either through your hosts package manager or using pip/easy_install.++*Note* [ReadTheDocs](http://www.readthedocs.org) works with Sphinx+ `v1.2.2`. If you install a more recent version of sphinx then+ 'incorrectly' marked up documentation may get passed the build system+ of readthedocs and be ignored. In the past we had several code-blocks+ disappear because of that.++The ReadTheDocs theme can be installed using pip as follows:++```sh+pip install sphinx_rtd_theme+```++### LaTeX++LaTeX can be install either using your systems package manager or direct from TeXLive.+++## Build Instructions++```sh+make html+make latexpdf+```++## Contributing++The documentation for Idris has been published under the Creative+Commons CC0 License. As such to the extent possible under law, /The+Idris Community/ has waived all copyright and related or neighboring+rights to Documentation for Idris.++More information concerning the CC0 can be found online at:++    http://creativecommons.org/publicdomain/zero/1.0/+++When contributing material to the manual please bear in mind that the work will be licensed as above.
+ docs/conf.py view
@@ -0,0 +1,368 @@+# -*- coding: utf-8 -*-+#+# Idris Manual documentation build configuration file, created by+# sphinx-quickstart on Sat Feb 28 20:41:47 2015.+#+# This file is execfile()d with the current directory set to its+# containing dir.+#+# Note that not all possible configuration values are present in this+# autogenerated file.+#+# All configuration values have a default; values that are commented out+# serve to show the default.++import sys+import os++# True if the readthedocs theme is locally installed+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'++# If extensions (or modules to document with autodoc) are in another directory,+# add these directories to sys.path here. If the directory is relative to the+# documentation root, use os.path.abspath to make it absolute, like shown here.+#sys.path.insert(0, os.path.abspath('.'))++# -- General configuration ------------------------------------------------++# If your documentation needs a minimal Sphinx version, state it here.+#needs_sphinx = '1.0'++# Add any Sphinx extension module names here, as strings. They can be+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom+# ones.+extensions = [+    'sphinx.ext.todo',+    'sphinx.ext.pngmath',+    'sphinx.ext.ifconfig',+]++# Add any paths that contain templates here, relative to this directory.+templates_path = ['_templates']++# The suffix of source filenames.+source_suffix = '.rst'++# The encoding of source files.+#source_encoding = 'utf-8-sig'++# The master toctree document.+master_doc = 'index'++# General information about the project.+project = u'Idris'+copyright = u'2015, The Idris Community'+author = u'The Idris Community'++# The version info for the project you're documenting, acts as replacement for+# |version| and |release|, also used in various other places throughout the+# built documents.+#+# The short X.Y version.+version = '0.12.3'+# The full version, including alpha/beta/rc tags.+release = '0.12.3'++# The language for content autogenerated by Sphinx. Refer to documentation+# for a list of supported languages.+#+# This is also used if you do content translation via gettext catalogs.+# Usually you set "language" from the command line for these cases.+language = None++# There are two options for replacing |today|: either, you set today to some+# non-false value, then it is used:+#today = ''+# Else, today_fmt is used as the format for a strftime call.+#today_fmt = '%B %d, %Y'++# List of patterns, relative to source directory, that match files and+# directories to ignore when looking for source files.+exclude_patterns = ['_build']++# The reST default role (used for this markup: `text`) to use for all+# documents.+#default_role = None++# If true, '()' will be appended to :func: etc. cross-reference text.+#add_function_parentheses = True++# If true, the current module name will be prepended to all description+# unit titles (such as .. function::).+#add_module_names = True++# If true, sectionauthor and moduleauthor directives will be shown in the+# output. They are ignored by default.+#show_authors = False++# The name of the Pygments (syntax highlighting) style to use.+pygments_style = 'sphinx'++# A list of ignored prefixes for module index sorting.+#modindex_common_prefix = []++# If true, keep warnings as "system message" paragraphs in the built documents.+#keep_warnings = False++# If true, `todo` and `todoList` produce output, else they produce nothing.+todo_include_todos = True+++# -- Options for HTML output ----------------------------------------------++# The theme to use for HTML and HTML Help pages.  See the documentation for+# a list of builtin themes.+html_theme = "default"++if not on_rtd:  # only import and set the theme if we're building docs locally+    try:+        import sphinx_rtd_theme+        html_theme = 'sphinx_rtd_theme'+        html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]+    except ImportError:+        html_theme = "default"++# Theme options are theme-specific and customize the look and feel of a theme+# further.  For a list of options available for each theme, see the+# documentation.+#html_theme_options = {}++# Add any paths that contain custom themes here, relative to this directory.+#html_theme_path = []++# The name for this set of Sphinx documents.  If None, it defaults to+# "<project> v<release> documentation".+#html_title = None++# A shorter title for the navigation bar.  Default is the same as html_title.+#html_short_title = None++# The name of an image file (relative to this directory) to place at the top+# of the sidebar.+#html_logo = None++# The name of an image file (within the static path) to use as favicon of the+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32+# pixels large.+#html_favicon = None++# Add any paths that contain custom static files (such as style sheets) here,+# relative to this directory. They are copied after the builtin static files,+# so a file named "default.css" will overwrite the builtin "default.css".+html_static_path = ['_static']++# Add any extra paths that contain custom files (such as robots.txt or+# .htaccess) here, relative to this directory. These files are copied+# directly to the root of the documentation.+#html_extra_path = []++# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,+# using the given strftime format.+#html_last_updated_fmt = '%b %d, %Y'++# If true, SmartyPants will be used to convert quotes and dashes to+# typographically correct entities.+#html_use_smartypants = True++# Custom sidebar templates, maps document names to template names.+#html_sidebars = {}++# Additional templates that should be rendered to pages, maps page names to+# template names.+#html_additional_pages = {}++# If false, no module index is generated.+#html_domain_indices = True++# If false, no index is generated.+#html_use_index = True++# If true, the index is split into individual pages for each letter.+#html_split_index = False++# If true, links to the reST sources are added to the pages.+#html_show_sourcelink = True++# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.+#html_show_sphinx = True++# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.+#html_show_copyright = True++# If true, an OpenSearch description file will be output, and all pages will+# contain a <link> tag referring to it.  The value of this option must be the+# base URL from which the finished HTML is served.+#html_use_opensearch = ''++# This is the file name suffix for HTML files (e.g. ".xhtml").+#html_file_suffix = None++# Language to be used for generating the HTML full-text search index.+# Sphinx supports the following languages:+#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'+#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'+#html_search_language = 'en'++# A dictionary with options for the search language support, empty by default.+# Now only 'ja' uses this config value+#html_search_options = {'type': 'default'}++# The name of a javascript file (relative to the configuration directory) that+# implements a search results scorer. If empty, the default will be used.+#html_search_scorer = 'scorer.js'++# Output file base name for HTML help builder.+htmlhelp_basename = 'IdrisManualdoc'++# -- Options for LaTeX output ---------------------------------------------++latex_elements = {+# The paper size ('letterpaper' or 'a4paper').+'papersize': 'a4paper',++# The font size ('10pt', '11pt' or '12pt').+'pointsize': '10pt',++# Additional stuff for the LaTeX preamble.+#'preamble': '',++# Latex figure (float) alignment+#'figure_align': 'htbp',+}++# Grouping the document tree into LaTeX files. List of tuples+# (source start file, target name, title,+#  author, documentclass [howto, manual, or own class]).+latex_documents = [+  ('tutorial/index',  'idris-tutorial.tex',  u'The Idris Tutorial',    u'The Idris Community', 'manual'),+  ('guides/index',    'idris-guides.tex',    u'Idris Tutorial Series', u'The Idris Community', 'manual'),+#  ('reference/index', 'idris-reference.tex', u'The Idris Reference',   u'The Idris Community', 'manual'),+    ('effects/index',  'eff-tutorial.tex',  u'The Effects Tutorial',    u'The Idris Community', 'manual')+    ]++# The name of an image file (relative to this directory) to place at the top of+# the title page.+#latex_logo = None++# For "manual" documents, if this is true, then toplevel headings are parts,+# not chapters.+#latex_use_parts = True++# If true, show page references after internal links.+#latex_show_pagerefs = False++# If true, show URL addresses after external links.+#latex_show_urls = False++# Documents to append as an appendix to all manuals.+#latex_appendices = []++# If false, no module index is generated.+#latex_domain_indices = True+++# -- Options for manual page output ---------------------------------------++# One entry per manual page. List of tuples+# (source start file, name, description, authors, manual section).+man_pages = [+    (master_doc, 'idrismanual', u'Idris Manual Documentation',+     [author], 1)+]++# If true, show URL addresses after external links.+#man_show_urls = False+++# -- Options for Texinfo output -------------------------------------------++# Grouping the document tree into Texinfo files. List of tuples+# (source start file, target name, title, author,+#  dir menu entry, description, category)+texinfo_documents = [+  (master_doc, 'IdrisManual', u'Idris Manual Documentation',+   author, 'IdrisManual', 'One line description of project.',+   'Miscellaneous'),+]++# Documents to append as an appendix to all manuals.+#texinfo_appendices = []++# If false, no module index is generated.+#texinfo_domain_indices = True++# How to display URL addresses: 'footnote', 'no', or 'inline'.+#texinfo_show_urls = 'footnote'++# If true, do not generate a @detailmenu in the "Top" node's menu.+#texinfo_no_detailmenu = False+++# -- Options for Epub output ----------------------------------------------++# Bibliographic Dublin Core info.+epub_title = project+epub_author = author+epub_publisher = author+epub_copyright = copyright++# The basename for the epub file. It defaults to the project name.+#epub_basename = project++# The HTML theme for the epub output. Since the default themes are not optimized+# for small screen space, using the same theme for HTML and epub output is+# usually not wise. This defaults to 'epub', a theme designed to save visual+# space.+#epub_theme = 'epub'++# The language of the text. It defaults to the language option+# or 'en' if the language is not set.+#epub_language = ''++# The scheme of the identifier. Typical schemes are ISBN or URL.+#epub_scheme = ''++# The unique identifier of the text. This can be a ISBN number+# or the project homepage.+#epub_identifier = ''++# A unique identification for the text.+#epub_uid = ''++# A tuple containing the cover image and cover page html template filenames.+#epub_cover = ()++# A sequence of (type, uri, title) tuples for the guide element of content.opf.+#epub_guide = ()++# HTML files that should be inserted before the pages created by sphinx.+# The format is a list of tuples containing the path and title.+#epub_pre_files = []++# HTML files shat should be inserted after the pages created by sphinx.+# The format is a list of tuples containing the path and title.+#epub_post_files = []++# A list of files that should not be packed into the epub file.+epub_exclude_files = ['search.html']++# The depth of the table of contents in toc.ncx.+#epub_tocdepth = 3++# Allow duplicate toc entries.+#epub_tocdup = True++# Choose between 'default' and 'includehidden'.+#epub_tocscope = 'default'++# Fix unsupported image types using the Pillow.+#epub_fix_images = False++# Scale large images.+#epub_max_image_width = 0++# How to display URL addresses: 'footnote', 'no', or 'inline'.+#epub_show_urls = 'inline'++# If false, no index is generated.+#epub_use_index = True
+ docs/effects/conclusions.rst view
@@ -0,0 +1,76 @@+.. _sect-further:++***************+Further Reading+***************++This tutorial has given an introduction to writing and reasoning about+side-effecting programs in Idris, using the ``Effects`` library.+More details about the *implementation* of the library, such as how+``run`` works, how handlers are invoked, etc, are given in a separate+paper [1]_.++Some libraries and programs which use ``Effects`` can be found in the+following places:++-  https://github.com/edwinb/SDL-idris — some bindings for the SDL media+   library, supporting graphics in particular.++-  https://github.com/edwinb/idris-demos — various demonstration+   programs, including several examples from this tutorial, and a “Space+   Invaders” game.++-  https://github.com/SimonJF/IdrisNet2 — networking and socket+   libraries.++-  https://github.com/edwinb/Protocols — a high level communication+   protocol description language.++The inspiration for the ``Effects`` library was Bauer and Pretnar’s+Eff language [2]_, which describes a language based on algebraic+effects and handlers.  Other recent languages and libraries have also+been built on this ideas, for example [3]_ and [4]_. The theoretical+foundations are also well-studied see [5]_, [6]_, [7]_, [8]_.++++.. [1] Edwin Brady. 2013. Programming and reasoning with algebraic+       effects and dependent types. SIGPLAN Not. 48, 9 (September+       2013), 133-144. DOI=10.1145/2544174.2500581+       https://dl.acm.org/citation.cfm?doid=2544174.2500581++.. [2] Andrej Bauer, Matija Pretnar, Programming with algebraic+       effects and handlers, Journal of Logical and Algebraic Methods+       in Programming, Volume 84, Issue 1, January 2015, Pages+       108-123, ISSN 2352-2208,+       http://math.andrej.com/wp-content/uploads/2012/03/eff.pdf+++.. [3] Ben Lippmeier. 2009. Witnessing Purity, Constancy and+       Mutability. In Proceedings of the 7th Asian Symposium on+       Programming Languages and Systems (APLAS '09), Zhenjiang Hu+       (Ed.). Springer-Verlag, Berlin, Heidelberg,+       95-110. DOI=10.1007/978-3-642-10672-9_9+       http://link.springer.com/chapter/10.1007%2F978-3-642-10672-9_9+++.. [4] Ohad Kammar, Sam Lindley, and Nicolas Oury. 2013. Handlers in+       action. SIGPLAN Not. 48, 9 (September 2013),+       145-158. DOI=10.1145/2544174.2500590+       https://dl.acm.org/citation.cfm?doid=2544174.2500590++.. [5] Martin Hyland, Gordon Plotkin, John Power, Combining effects:+       Sum and tensor, Theoretical Computer Science, Volume 357,+       Issues 1–3, 25 July 2006, Pages 70-99, ISSN 0304-3975,+       (https://www.sciencedirect.com/science/article/pii/S0304397506002659)++.. [6] Paul Blain Levy. 2004. Call-By-Push-Value: A+       Functional/Imperative Synthesis (Semantics Structures in+       Computation, V. 2). Kluwer Academic Publishers, Norwell, MA,+       USA.++.. [7] Plotkin, Gordon, and Matija Pretnar. "Handlers of algebraic+       effects." Programming Languages and Systems. Springer Berlin+       Heidelberg, 2009. 80-94.++.. [8] Pretnar, Matija. "Logic and handling of algebraic effects." (2010).
+ docs/effects/depeff.rst view
@@ -0,0 +1,333 @@+.. _sect-depeff:++*****************+Dependent Effects+*****************++In the programs we have seen so far, the available effects have remained+constant. Sometimes, however, an operation can *change* the available+effects. The simplest example occurs when we have a state with a+dependent type—adding an element to a vector also changes its type, for+example, since its length is explicit in the type. In this section, we+will see how the library supports this. Firstly, we will see how states+with dependent types can be implemented. Secondly, we will see how the+effects can depend on the *result* of an effectful operation. Finally,+we will see how this can be used to implement a type-safe and+resource-safe protocol for file management.++Dependent States+================++Suppose we have a function which reads input from the console, converts+it to an integer, and adds it to a list which is stored in a ``STATE``.+It might look something like the following:++.. code-block:: idris++    readInt : Eff () [STATE (List Int), STDIO] +    readInt = do let x = trim !getStr+                 put (cast x :: !get)++But what if, instead of a list of integers, we would like to store a+``Vect``, maintaining the length in the type?++.. code-block:: idris++    readInt : Eff () [STATE (Vect n Int), STDIO]+    readInt = do let x = trim !getStr+                 put (cast x :: !get)++This will not type check! Although the vector has length ``n`` on entry+to ``readInt``, it has length ``S n`` on exit. The library allows us to+express this as follows:++.. code-block:: idris++    readInt : Eff ()[STATE (Vect n Int), STDIO] +                    [STATE (Vect (S n) Int), STDIO]+    readInt = do let x = trim !getStr+                 putM (cast x :: !get)++The type ``Eff a xs xs'`` means that the operation+begins with effects ``xs`` available, and ends with effects ``xs’``+available. We have used ``putM`` to update the state, where the ``M``+suffix indicates that the *type* is being updated as well as the value.+It has the following type:++.. code-block:: idris++    putM : y -> Eff () [STATE x] [STATE y]++Result-dependent Effects+========================++Often, whether a state is updated could depend on the success or+otherwise of an operation. In our ``readInt`` example, we might wish to+update the vector only if the input is a valid integer (i.e. all+digits). As a first attempt, we could try the following, returning a+``Bool`` which indicates success:++.. code-block:: idris++    readInt : Eff Bool [STATE (Vect n Int), STDIO]+                       [STATE (Vect (S n) Int), STDIO]+    readInt = do let x = trim !getStr+                 case all isDigit (unpack x) of+                      False => pure False+                      True => do putM (cast x :: !get)+                                 pure True++Unfortunately, this will not type check because the vector does not get+extended in both branches of the ``case``!++::++    MutState.idr:18:19:When elaborating right hand side of Main.case+    block in readInt:+    Unifying n and S n would lead to infinite value++Clearly, the size of the resulting vector depends on whether or not the+value read from the user was valid. We can express this in the type:++.. code-block:: idris++    readInt : Eff Bool [STATE (Vect n Int), STDIO]+                (\ok => if ok then [STATE (Vect (S n) Int), STDIO]+                              else [STATE (Vect n Int), STDIO])+    readInt = do let x = trim !getStr+                 case all isDigit (unpack x) of+                      False => pureM False+                      True => do putM (cast x :: !get)+                                 pureM True++Using ``pureM`` rather than ``pure`` allows the output effects to be+calculated from the value given. Its type is:++.. code-block:: idris++    pureM : (val : a) -> EffM m a (xs val) xs++When using ``readInt``, we will have to check its return+value in order to know what the new set of effects is. For example, to+read a set number of values into a vector, we could write the following:++.. code-block:: idris++    readN : (n : Nat) ->+            Eff () [STATE (Vect m Int), STDIO]+                   [STATE (Vect (n + m) Int), STDIO]+    readN Z = pure ()+    readN {m} (S k) = case !readInt of+                          True => rewrite plusSuccRightSucc k m in readN k+                          False => readN (S k)++The ``case`` analysis on the result of ``readInt`` means that we know in+each branch whether reading the integer succeeded, and therefore how+many values still need to be read into the vector. What this means in+practice is that the type system has verified that a necessary dynamic+check (i.e. whether reading a value succeeded) has indeed been done.++.. note::+    Only ``case`` will work here. We cannot use ``if/then/else``+    because the ``then`` and ``else`` branches must have the same+    type. The ``case`` construct, however, abstracts over the value+    being inspected in the type of each branch.++File Management+===============++A practical use for dependent effects is in specifying resource usage+protocols and verifying that they are executed correctly. For example,+file management follows a resource usage protocol with the following+(informally specified) requirements:++-  It is necessary to open a file for reading before reading it++-  Opening may fail, so the programmer should check whether opening was+   successful++-  A file which is open for reading must not be written to, and vice+   versa++-  When finished, an open file handle should be closed++-  When a file is closed, its handle should no longer be used++These requirements can be expressed formally in , by creating a+``FILE_IO`` effect parameterised over a file handle state, which is+either empty, open for reading, or open for writing. The ``FILE_IO``+effect’s definition is given below. Note that this+effect is mainly for illustrative purposes—typically we would also like+to support random access files and better reporting of error conditions.++.. code-block:: idris++    module Effect.File++    import Effects+    import Control.IOExcept++    FILE_IO : Type -> EFFECT++    data OpenFile : Mode -> Type++    open : (fname : String)+           -> (m : Mode)+           -> Eff Bool [FILE_IO ()] +                       (\res => [FILE_IO (case res of+                                               True => OpenFile m+                                               False => ())])+    close : Eff () [FILE_IO (OpenFile m)] [FILE_IO ()]++    readLine  : Eff String [FILE_IO (OpenFile Read)]+    writeLine : String -> Eff () [FILE_IO (OpenFile Write)]+    eof       : Eff Bool [FILE_IO (OpenFile Read)]++    Handler FileIO IO where { ... }++In particular, consider the type of ``open``:++.. code-block:: idris++    open : (fname : String)+           -> (m : Mode)+           -> Eff Bool [FILE_IO ()] +                       (\res => [FILE_IO (case res of+                                               True => OpenFile m+                                               False => ())])++This returns a ``Bool`` which indicates whether opening the file was+successful. The resulting state depends on whether the operation was+successful; if so, we have a file handle open for the stated purpose,+and if not, we have no file handle. By ``case`` analysis on the result,+we continue the protocol accordingly.++.. _eff-readfile:+.. code-block:: idris++    readFile : Eff (List String) [FILE_IO (OpenFile Read)]+    readFile = readAcc [] where+        readAcc : List String -> Eff (List String) [FILE_IO (OpenFile Read)] +        readAcc acc = if (not !eof)+                         then readAcc (!readLine :: acc)+                         else pure (reverse acc)++Given a function ``readFile``, above, which reads from+an open file until reaching the end, we can write a program which opens+a file, reads it, then displays the contents and closes it, as follows,+correctly following the protocol:++.. code-block:: idris++    dumpFile : String -> Eff () [FILE_IO (), STDIO]+    dumpFile name = case !(open name Read) of+                        True => do putStrLn (show !readFile)+                                   close+                        False => putStrLn ("Error!")++The type of ``dumpFile``, with ``FILE_IO ()`` in its effect list,+indicates that any use of the file resource will follow the protocol+correctly (i.e. it both begins and ends with an empty resource). If we+fail to follow the protocol correctly (perhaps by forgetting to close+the file, failing to check that ``open`` succeeded, or opening the file+for writing) then we will get a compile-time error. For example,+changing ``open name Read`` to ``open name Write`` yields a compile-time+error of the following form:++::++    FileTest.idr:16:18:When elaborating right hand side of Main.case+    block in testFile:+    Can't solve goal+            SubList [(FILE_IO (OpenFile Read))]+                    [(FILE_IO (OpenFile Write)), STDIO]++In other words: when reading a file, we need a file which is open for+reading, but the effect list contains a ``FILE_IO`` effect carrying a+file open for writing.++Pattern-matching bind+=====================++It might seem that having to test each potentially failing operation+with a ``case`` clause could lead to ugly code, with lots of+nested case blocks. Many languages support exceptions to improve this,+but unfortunately exceptions may not allow completely clean resource+management—for example, guaranteeing that any ``open`` which did succeed+has a corresponding close.++Idris supports *pattern-matching* bindings, such as the following:++.. code-block:: idris++    dumpFile : String -> Eff () [FILE_IO (), STDIO]+    dumpFile name = do True <- open name Read+                       putStrLn (show !readFile)+                       close++This also has a problem: we are no longer dealing with the case where+opening a file failed! The solution is to extend the pattern-matching+binding syntax to give brief clauses for failing matches. Here, for+example, we could write:++.. code-block:: idris++    dumpFile : String -> Eff () [FILE_IO (), STDIO]+    dumpFile name  = do True <- open name Read | False => putStrLn "Error"+                        putStrLn (show !readFile)+                        close++This is exactly equivalent to the definition with the explicit ``case``.+In general, in a ``do``-block, the syntax:++.. code-block:: idris++    do pat <- val | <alternatives>+       p++is desugared to++.. code-block:: idris++    do x <- val+       case x of+            pat => p+            <alternatives>++There can be several ``alternatives``, separated by a vertical bar+``|``. For example, there is a ``SYSTEM`` effect which supports+reading command line arguments, among other things (see Appendix+:ref:`sect-appendix`). To read command line arguments, we can use+``getArgs``:++.. code-block:: idris++    getArgs : Eff (List String) [SYSTEM]++A main program can read command line arguments as follows, where in the+list which is returned, the first element ``prog`` is the executable+name and the second is an expected argument:++.. code-block:: idris++    emain : Eff () [SYSTEM, STDIO]+    emain = do [prog, arg] <- getArgs+               putStrLn $ "Argument is " ++ arg+               {- ... rest of function ... -}++Unfortunately, this will not fail gracefully if no argument is given, or+if too many arguments are given. We can use pattern matching bind+alternatives to give a better (more informative) error:++.. code-block:: idris++    emain : Eff () [SYSTEM, STDIO]+    emain = do [prog, arg] <- getArgs | [] => putStrLn "Can't happen!"+                                      | [prog] => putStrLn "No arguments!"+                                      | _ => putStrLn "Too many arguments!"+               putStrLn $ "Argument is " ++ arg+               {- ... rest of function ... -}++If ``getArgs`` does not return something of the form ``[prog, arg]`` the+alternative which does match is executed instead, and that value+returned.
+ docs/effects/hangman.rst view
@@ -0,0 +1,329 @@+.. _sect-hangman:++***************************************+Example: A “Mystery Word” Guessing Game+***************************************++In this section, we will use the techniques and specific effects+discussed in the tutorial so far to implement a larger example, a simple+text-based word-guessing game. In the game, the computer chooses a word,+which the player must guess letter by letter. After a limited number of+wrong guesses, the player loses [1]_.++We will implement the game by following these steps:++#. Define the game state, in enough detail to express the rules++#. Define the rules of the game (i.e. what actions the player may take,+   and how these actions affect the game state)++#. Implement the rules of the game (i.e. implement state updates for+   each action)++#. Implement a user interface which allows a player to direct actions++Step 2 may be achieved by defining an effect which depends on the state+defined in step 1. Then step 3 involves implementing a ``Handler`` for+this effect. Finally, step 4 involves implementing a program in ``Eff``+using the newly defined effect (and any others required to implement the+interface).++Step 1: Game State+==================++First, we categorise the game states as running games (where there are a+number of guesses available, and a number of letters still to guess), or+non-running games (i.e. games which have not been started, or games+which have been won or lost).++.. code-block:: idris++    data GState = Running Nat Nat | NotRunning++Notice that at this stage, we say nothing about what it means to make a+guess, what the word to be guessed is, how to guess letters, or any+other implementation detail. We are only interested in what is necessary+to describe the game rules.++We will, however, parameterise a concrete game state ``Mystery`` over+this data:++.. code-block:: idris++    data Mystery : GState -> Type++Step 2: Game Rules+==================++We describe the game rules as a dependent effect, where each action has+a *precondition* (i.e. what the game state must be before carrying out+the action) and a *postcondition* (i.e. how the action affects the game+state). Informally, these actions with the pre- and postconditions are:++Guess+    Guess a letter in the word.++    -  Precondition: The game must be running, and there must be both+       guesses still available, and letters still to be guessed.++    -  Postcondition: If the guessed letter is in the word and not yet+       guessed, reduce the number of letters, otherwise reduce the+       number of guesses.++Won+    Declare victory++    -  Precondition: The game must be running, and there must be no+       letters still to be guessed.++    -  Postcondition: The game is no longer running.++Lost+    Accept defeat++    -  Precondition: The game must be running, and there must be no+       guesses left.++    -  Postcondition: The game is no longer running.++NewWord+    Set a new word to be guessed++    -  Precondition: The game must not be running.++    -  Postcondition: The game is running, with 6 guesses available (the+       choice of 6 is somewhat arbitrary here) and the number of unique+       letters in the word still to be guessed.++Get+    Get a string representation of the game state. This is for display+    purposes; there are no pre- or postconditions.++We can make these rules precise by declaring them more formally in an+effect signature:++.. code-block:: idris++    data MysteryRules : Effect where+         Guess : (x : Char) ->+                 sig MysteryRules Bool+                     (Mystery (Running (S g) (S w)))+                     (\inword => if inword+                                 then Mystery (Running (S g) w)+                                 else Mystery (Running g (S w)))+         Won  : sig MysteryRules () (Mystery (Running g 0))+                                    (Mystery NotRunning)+         Lost : sig MysteryRules () (Mystery (Running 0 g))+                                    (Mystery NotRunning)+         NewWord : (w : String) -> +                   sig MysteryRules () (Mystery NotRunning) (Mystery (Running 6 (length (letters w))))+         Get : sig MysteryRules String (Mystery h)++This description says nothing about how the rules are implemented. In+particular, it does not specify *how* to tell whether a guessed letter+was in a word, just that the result of ``Guess`` depends on it.++Nevertheless, we can still create an ``EFFECT`` from this, and use it in+an ``Eff`` program. Implementing a ``Handler`` for ``MysteryRules`` will+then allow us to play the game.++.. code-block:: idris++    MYSTERY : GState -> EFFECT+    MYSTERY h = MkEff (Mystery h) MysteryRules++Step 3: Implement Rules+=======================++To *implement* the rules, we begin by giving a concrete definition of+game state:++.. code-block:: idris++    data Mystery : GState -> Type where+         Init     : Mystery NotRunning+         GameWon  : (word : String) -> Mystery NotRunning+         GameLost : (word : String) -> Mystery NotRunning+         MkG      : (word : String) ->+                    (guesses : Nat) ->+                    (got : List Char) ->+                    (missing : Vect m Char) ->+                    Mystery (Running guesses m)++If a game is ``NotRunning``, that is either because it has not yet+started (``Init``) or because it is won or lost (``GameWon`` and+``GameLost``, each of which carry the word so that showing the game+state will reveal the word to the player). Finally, ``MkG`` captures a+running game’s state, including the target word, the letters+successfully guessed, and the missing letters. Using a ``Vect`` for the+missing letters is convenient since its length is used in the type.++To initialise the state, we implement the following functions:+``letters``, which returns a list of unique letters in a ``String``+(ignoring spaces) and ``initState`` which sets up an initial state+considered valid as a postcondition for ``NewWord``.++.. code-block:: idris++    letters : String -> List Char+    initState : (x : String) -> Mystery (Running 6 (length (letters x)))++When checking if a guess is in the vector of missing letters, it is+convenient to return a *proof* that the guess is in the vector, using+``isElem`` below, rather than merely a ``Bool``:++.. code-block:: idris++    data IsElem : a -> Vect n a -> Type where+         First : IsElem x (x :: xs)+         Later : IsElem x xs -> IsElem x (y :: xs)++    isElem : DecEq a => (x : a) -> (xs : Vect n a) -> Maybe (IsElem x xs)++The reason for returning a proof is that we can use it to remove an+element from the correct position in a vector:++.. code-block:: idris++    shrink : (xs : Vect (S n) a) -> IsElem x xs -> Vect n a++We leave the definitions of ``letters``, ``init``, ``isElem`` and+``shrink`` as exercises. Having implemented these, the ``Handler``+implementation for ``MysteryRules`` is surprisingly straightforward:++.. code-block:: idris++    Handler MysteryRules m where+        handle (MkG w g got []) Won k = k () (GameWon w)+        handle (MkG w Z got m) Lost k = k () (GameLost w)++        handle st Get k = k (show st) st+        handle st (NewWord w) k = k () (initState w)++        handle (MkG w (S g) got m) (Guess x) k =+            case isElem x m of+                 Nothing => k False (MkG w _ got m)+                 (Just p) => k True (MkG w _ (x :: got) (shrink m p))++Each case simply involves directly updating the game state in a way+which is consistent with the declared rules. In particular, in+``Guess``, if the handler claims that the guessed letter is in the word+(by passing ``True`` to ``k``), there is no way to update the state in+such a way that the number of missing letters or number of guesses does+not follow the rules.++Step 4: Implement Interface+===========================++Having described the rules, and implemented state transitions which+follow those rules as an effect handler, we can now write an interface+for the game which uses the ``MYSTERY`` effect:++.. code-block:: idris++    game : Eff () [MYSTERY (Running (S g) w), STDIO]+                  [MYSTERY NotRunning, STDIO]++The type indicates that the game must start in a running state, with+some guesses available, and eventually reach a not-running state (i.e.+won or lost). The only way to achieve this is by correctly following the+stated rules.++Note that the type of ``game`` makes no assumption that there are+letters to be guessed in the given word (i.e. it is ``w`` rather than+``S w``). This is because we will be choosing a word at random from a+vector of ``String``, and at no point have we made it explicit that+those ``String`` are non-empty.++Finally, we need to initialise the game by picking a word at random from+a list of candidates, setting it as the target using ``NewWord``, then+running ``game``:++.. code-block:: idris++    runGame : Eff () [MYSTERY NotRunning, RND, SYSTEM, STDIO]+    runGame = do srand !time+                 let w = index !(rndFin _) words+                 call $ NewWord w+                 game+                 putStrLn !(call Get)++We use the system time (``time`` from the ``SYSTEM`` effect; see+Appendix :ref:`sect-appendix`) to initialise the random number+generator, then pick a random ``Fin`` to index into a list of+``words``. For example, we could initialise a word list as follows:++.. code-block:: idris++    words : ?wtype+    words = with Vect ["idris","agda","haskell","miranda",+             "java","javascript","fortran","basic",+             "coffeescript","rust"]++    wtype = proof search++.. note::+    Rather than have to explicitly declare a type with the vector’s+    length, it is convenient to give a hole ``?wtype`` and let+    Idris’s proof search mechanism find the type. This is a+    limited form of type inference, but very useful in practice.++A possible complete implementation of ``game`` is+presented below:++.. code-block:: idris++    game : Eff () [MYSTERY (Running (S g) w), STDIO]+                  [MYSTERY NotRunning, STDIO]+    game {w=Z} = Won+    game {w=S _}+         = do putStrLn !Get+              putStr "Enter guess: "+              let guess = trim !getStr+              case choose (not (guess == "")) of+                   (Left p) => processGuess (strHead' guess p)+                   (Right p) => do putStrLn "Invalid input!"+                                   game+      where+        processGuess : Char -> Eff () [MYSTERY (Running (S g) (S w)), STDIO]+                                      [MYSTERY NotRunning, STDIO]+        processGuess {g} {w} c+          = case !(Main.Guess c) of+                 True => do putStrLn "Good guess!"+                            case w of+                                 Z => Won+                                 (S k) => game+                 False => do putStrLn "No, sorry"+                             case g of+                                  Z => Lost+                                  (S k) => game++Discussion+==========++Writing the rules separately as an effect, then an implementation+which uses that effect, ensures that the implementation must follow+the rules.  This has practical applications in more serious contexts;+``MysteryRules`` for example can be though of as describing a+*protocol* that a game player most follow, or alternative a+*precisely-typed API*.++In practice, we wouldn’t really expect to write rules first then+implement the game once the rules were complete. Indeed, I didn’t do+so when constructing this example! Rather, I wrote down a set of+likely rules making any assumptions *explicit* in the state+transitions for ``MysteryRules``. Then, when implementing ``game`` at+first, any incorrect assumption was caught as a type error. The+following errors were caught during development:++- Not realising that allowing ``NewWord`` to be an arbitrary string would mean that ``game`` would have to deal with a zero-length word as a starting state.++- Forgetting to check whether a game was won before recursively calling ``processGuess``, thus accidentally continuing a finished game.++- Accidentally checking the number of missing letters, rather than the number of remaining guesses, when checking if a game was lost.++These are, of course, simple errors, but were caught by the type+checker before any testing of the game.++.. [1]+   Readers may recognise this game by the name “Hangman”.
+ docs/effects/impleff.rst view
@@ -0,0 +1,333 @@+.. _sect-impleff:++********************+Creating New Effects+********************++We have now seen several side-effecting operations provided by the+``Effects`` library, and examples of their use in Section+:ref:`sect-simpleff`. We have also seen how operations may *modify*+the available effects by changing state in Section+:ref:`sect-depeff`. We have not, however, yet seen how these+operations are implemented. In this section, we describe how a+selection of the available effects are implemented, and show how new+effectful operations may be provided.++State+=====++Effects are described by *algebraic data types*, where the+constructors describe the operations provided when the effect is+available. Stateful operations are described as follows:++.. code-block:: idris++    data State : Effect where+         Get :      State a  a (\x => a)+         Put : b -> State () a (\x => b)++``Effect`` itself is a type synonym, giving the required type for an+effect signature:++.. code-block:: idris++    Effect : Type+    Effect = (result : Type) ->+             (input_resource : Type) ->+             (output_resource : result -> Type) -> Type++Each effect is associated with a *resource*. The second argument to+an effect signature is the resource type on *input* to an operation,+and the third is a function which computes the resource type on+*output*. Here, it means:++- ``Get`` takes no arguments. It has a resource of type ``a``, which is not updated, and running the ``Get`` operation returns something of type ``a``.++- ``Put`` takes a ``b`` as an argument. It has a resource of type ``a`` on input, which is updated to a resource of type ``b``. Running the ``Put`` operation returns the element of the unit type.++The effects library provides an overloaded function ``sig``+which can make effect signatures more concise, particularly when the+result has no effect on the resource type. For ``State``, we can+write:++.. code-block:: idris++    data State : Effect where+         Get :      sig State a  a+         Put : b -> sig State () a b++There are four versions of ``sig``, depending on whether we+are interested in the resource type, and whether we are updating the+resource. Idris will infer the appropriate version from usage.++.. code-block:: idris++    NoResourceEffect.sig : Effect -> Type -> Type+    NoUpdateEffect.sig   : Effect -> (ret : Type) -> +                                     (resource : Type) -> Type+    UpdateEffect.sig     : Effect -> (ret : Type) -> +                                     (resource_in : Type) -> +                                     (resource_out : Type) -> Type+    DepUpdateEffect.sig  : Effect -> (ret : Type) -> +                                     (resource_in : Type) -> +                                     (resource_out : ret -> Type) -> Type++In order to convert ``State`` (of type ``Effect``) into something+usable in an effects list, of type ``EFFECT``, we write the following:++.. code-block:: idris++    STATE : Type -> EFFECT+    STATE t = MkEff t State++``MkEff`` constructs an ``EFFECT`` by taking the resource type (here,+the ``t`` which parameterises ``STATE``) and the effect signature+(here, ``State``). For reference, ``EFFECT`` is declared as follows:++.. code-block:: idris++    data EFFECT : Type where+         MkEff : Type -> Effect -> EFFECT++Recall that to run an effectful program in ``Eff``, we use one of the+``run`` family of functions to run the program in a particular+computation context ``m``. For each effect, therefore, we must explain+how it is executed in a particular computation context for ``run`` to+work in that context. This is achieved with the following interface:++.. code-block:: idris++    interface Handler (e : Effect) (m : Type -> Type) where+          handle : resource -> (eff : e t resource resource') ->+                   ((x : t) -> resource' x -> m a) -> m a++We have already seen some implementation declarations in the effect+summaries in Section :ref:`sect-simpleff`. An implementation of ``Handler e+m`` means that the effect declared with signature ``e`` can be run in+computation context ``m``. The ``handle`` function takes:++- The ``resource`` on input (so, the current value of the state for ``State``)++- The effectful operation (either ``Get`` or ``Put x`` for ``State``)++- A *continuation*, which we conventionally call ``k``, and should be passed the result value of the operation, and an updated resource.++There are two reasons for taking a continuation here: firstly, this is+neater because there are multiple return values (a new resource and+the result of the operation); secondly, and more importantly, the+continuation can be called zero or more times.++A ``Handler`` for ``State`` simply passes on the value of the state,+in the case of ``Get``, or passes on a new state, in the case of+``Put``.  It is defined the same way for all computation contexts:++.. code-block:: idris++    Handler State m where+         handle st Get     k = k st st+         handle st (Put n) k = k () n++This gives enough information for ``Get`` and ``Put`` to be used+directly in ``Eff`` programs. It is tidy, however, to define top level+functions in ``Eff``, as follows:++.. code-block:: idris++    get : Eff x [STATE x]+    get = call Get++    put : x -> Eff () [STATE x]+    put val = call (Put val)++    putM : y -> Eff () [STATE x] [STATE y]+    putM val = call (Put val)++**An implementation detail (aside):** The ``call`` function converts+an ``Effect`` to a function in ``Eff``, given a proof that the effect+is available. This proof can be constructed automatically by , since+it is essentially an index into a statically known list of effects:++.. code-block:: idris++    call : {e : Effect} ->+           (eff : e t a b) -> {auto prf : EffElem e a xs} ->+           Eff t xs (\v => updateResTy v xs prf eff)++This is the reason for the ``Can’t solve goal`` error when an effect+is not available: the implicit proof ``prf`` has not been solved+automatically because the required effect is not in the list of+effects ``xs``.++Such details are not important for using the library, or even writing+new effects, however.++Summary+-------++The following listing summarises what is required to define the+``STATE`` effect:++.. code-block:: idris++    data State : Effect where+         Get :      sig State a  a+         Put : b -> sig State () a b++    STATE : Type -> EFFECT+    STATE t = MkEff t State++    Handler State m where+         handle st Get     k = k st st+         handle st (Put n) k = k () n++    get : Eff x [STATE x]+    get = call Get++    put : x -> Eff () [STATE x]+    put val = call (Put val)++    putM : y -> Eff () [STATE x] [STATE y]+    putM val = call (Put val)+++Console I/O+===========++Then listing below gives the definition of the ``STDIO``+effect, including handlers for ``IO`` and ``IOExcept``. We omit the+definition of the top level ``Eff`` functions, as this merely invoke+the effects ``PutStr``, ``GetStr``, ``PutCh`` and ``GetCh`` directly.++Note that in this case, the resource is the unit type in every case,+since the handlers merely apply the ``IO`` equivalents of the effects+directly.++.. _eff-stdiodef:+.. code-block:: idris++    data StdIO : Effect where+         PutStr : String -> sig StdIO ()+         GetStr : sig StdIO String+         PutCh : Char -> sig StdIO ()+         GetCh : sig StdIO Char++    Handler StdIO IO where+        handle () (PutStr s) k = do putStr s; k () ()+        handle () GetStr     k = do x <- getLine; k x ()+        handle () (PutCh c)  k = do putChar c; k () ()+        handle () GetCh      k = do x <- getChar; k x ()++    Handler StdIO (IOExcept a) where+        handle () (PutStr s) k = do ioe_lift $ putStr s; k () ()+        handle () GetStr     k = do x <- ioe_lift $ getLine; k x ()+        handle () (PutCh c)  k = do ioe_lift $ putChar c; k () ()+        handle () GetCh      k = do x <- ioe_lift $ getChar; k x ()++    STDIO : EFFECT+    STDIO = MkEff () StdIO++Exceptions+==========++The listing below gives the definition of the ``Exception``+effect, including two of its handlers for ``Maybe`` and ``List``. The+only operation provided is ``Raise``. The key point to note in the+definitions of these handlers is that the continuation ``k`` is not+used. Running ``Raise`` therefore means that computation stops with an+error.++.. code-block:: idris++    data Exception : Type -> Effect where+         Raise : a -> sig (Exception a) b++    Handler (Exception a) Maybe where+         handle _ (Raise e) k = Nothing++    Handler (Exception a) List where+         handle _ (Raise e) k = []++    EXCEPTION : Type -> EFFECT+    EXCEPTION t = MkEff () (Exception t)+++Non-determinism+===============++The following listing gives the definition of the ``Select``+effect for writing non-deterministic programs, including a handler for+``List`` context which returns all possible successful values, and a+handler for ``Maybe`` context which returns the first successful+value.++.. code-block:: idris++    data Selection : Effect where+         Select : List a -> sig Selection a++    Handler Selection Maybe where+         handle _ (Select xs) k = tryAll xs where+             tryAll [] = Nothing+             tryAll (x :: xs) = case k x () of+                                     Nothing => tryAll xs+                                     Just v => Just v++    Handler Selection List where+         handle r (Select xs) k = concatMap (\x => k x r) xs++    SELECT : EFFECT+    SELECT = MkEff () Selection+++Here, the continuation is called multiple times in each handler, for+each value in the list of possible values. In the ``List`` handler, we+accumulate all successful results, and in the ``Maybe`` handler we try+the first value in the list, and try later values only if that fails.++File Management+===============++Result-dependent effects are no different from non-dependent effects+in the way they are implemented. The listing below+illustrates this for the ``FILE_IO`` effect. The syntax for state+transitions ``{ x ==> {res} x’ }``, where the result state ``x’`` is+computed from the result of the operation ``res``, follows that for+the equivalent ``Eff`` programs.++.. code-block:: idris++    data FileIO : Effect where+         Open : (fname: String)+                -> (m : Mode)+                -> sig FileIO Bool () (\res => case res of+                                                    True => OpenFile m+                                                    False => ())+         Close : sig FileIO () (OpenFile m)++         ReadLine  :           sig FileIO String (OpenFile Read)+         WriteLine : String -> sig FileIO ()     (OpenFile Write)+         EOF       :           sig FileIO Bool   (OpenFile Read)++    Handler FileIO IO where+        handle () (Open fname m) k = do h <- openFile fname m+                                        if !(validFile h)+                                                 then k True (FH h)+                                                 else k False ()+        handle (FH h) Close      k = do closeFile h+                                        k () ()++        handle (FH h) ReadLine        k = do str <- fread h+                                             k str (FH h)+        handle (FH h) (WriteLine str) k = do fwrite h str+                                             k () (FH h)+        handle (FH h) EOF             k = do e <- feof h+                                             k e (FH h)++    FILE_IO : Type -> EFFECT+    FILE_IO t = MkEff t FileIO++Note that in the handler for ``Open``, the types passed to the+continuation ``k`` are different depending on whether the result is+``True`` (opening succeeded) or ``False`` (opening failed). This uses+``validFile``, defined in the ``Prelude``, to test whether a file+handler refers to an open file or not.
+ docs/effects/index.rst view
@@ -0,0 +1,28 @@+.. _eff-tutorial-index:++####################+The Effects Tutorial+####################++A tutorial on the `Effects` package in `Idris`.++.. note::++   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighbouring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/++.. toctree::+   :maxdepth: 1++   introduction+   state+   simpleeff+   depeff+   impleff+   hangman+   conclusions+   summary
+ docs/effects/introduction.rst view
@@ -0,0 +1,109 @@+************+Introduction+************++Pure functional languages with dependent types such as `Idris+<http://www.idris-lang.org/>`_ support reasoning about programs directly+in the type system, promising that we can *know* a program will run+correctly (i.e. according to the specification in its type) simply+because it compiles. Realistically, though, things are not so simple:+programs have to interact with the outside world, with user input,+input from a network, mutable state, and so on. In this tutorial I+will introduce the library, which is included with the distribution+and supports programming and reasoning with side-effecting programs,+supporting mutable state, interaction with the outside world,+exceptions, and verified resource management.++This tutorial assumes familiarity with pure programming in Idris,+as described in Sections 1–6 of the main tutorial [1]_. The examples+presented are tested with Idris and can be found in the+examples directory of the Idris repository.++Consider, for example, the following introductory function which+illustrates the kind of properties which can be expressed in the type+system:++.. code-block:: idris++   vadd : Vect n Int -> Vect n Int -> Vect n Int+   vadd []        []        = []+   vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys++This function adds corresponding elements in a pair of vectors. The type+guarantees that the vectors will contain only elements of type ``Int``,+and that the input lengths and the output length all correspond. A+natural question to ask here, which is typically neglected by+introductory tutorials, is “How do I turn this into a program?” That is,+given some lists entered by a user, how do we get into a position to be+able to apply the ``vadd`` function? Before doing so, we will have to:++- Read user input, either from the keyboard, a file, or some other input device.++- Check that the user inputs are valid, i.e. contain only ``Int`` and are the same length, and report an error if not.++- Write output++The complete program will include side-effects for I/O and error+handling, before we can get to the pure core functionality. In this+tutorial, we will see how Idris supports side-effects.+Furthermore, we will see how we can use the dependent type system to+*reason* about stateful and side-effecting programs. We will return to+this specific example later.++Hello world+===========++To give an idea of how programs with effects look in , here is the+ubiquitous “Hello world” program, written using the ``Effects``+library:++.. code-block:: idris++   module Main++   import Effects+   import Effect.StdIO++   hello : Eff () [STDIO]+   hello = putStrLn “Hello world!”++   main : IO ()+   main = run hello++As usual, the entry point is ``main``. All ``main`` has to do is invoke the+``hello`` function which supports the ``STDIO`` effect for console I/O, and+returns the unit value.  All programs using the ``Effects`` library must+``import Effects``.  The details of the ``Eff`` type will be presented in the+remainder of this tutorial.++To compile and run this program, Idris needs to be told to include+the ``Effects`` package, using the ``-p effects`` flag (this flag is+required for all examples in this tutorial):++.. code-block:: sh++   idris hello.idr -o hello -p effects+   ./hello Hello world!++Outline+=======++The tutorial is structured as follows: first, in Section+:ref:`sect-state`, we will discuss state management, describing why it+is important and introducing the ``effects`` library to show how it+can be used to manage state. This section also gives an overview of+the syntax of effectful programs. Section :ref:`sect-simpleff` then+introduces a number of other effects a program may have: I/O;+Exceptions; Random Numbers; and Non-determinism, giving examples for+each, and an extended example combining several effects in one+complete program. Section :ref:`sect-depeff` introduces *dependent*+effects, showing how states and resources can be managed in+types. Section :ref:`sect-impleff` shows how new effects can be+implemented.  Section :ref:`sect-hangman` gives an extended example+showing how to implement a “mystery word” guessing game, using effects+to describe the rules of the game and ensure they are implemented+accurately. References to further reading are given in Section+:ref:`sect-further`.++.. [1]+   You do not, however, need to know what a monad is!
+ docs/effects/simpleeff.rst view
@@ -0,0 +1,594 @@+.. _sect-simpleff:++**************+Simple Effects+**************++So far we have seen how to write programs with locally mutable state+using the ``STATE`` effect. To recap, we have the definitions below+in a module ``Effect.State``++.. code-block:: idris++    module Effect.State++    STATE : Type -> EFFECT++    get    :             Eff x  [STATE x]+    put    : x ->        Eff () [STATE x]+    putM   : y ->        Eff () [STATE x] [STATE y]+    update : (x -> x) -> Eff () [STATE x]++    Handler State m where { ... }++The last line, ``Handler State m where { ... }``, means that the ``STATE``+effect is usable in any computation context ``m``. That is, a program+which uses this effect and returns something of type ``a`` can be+evaluated to something of type ``m a`` using ``run``, for any+``m``. The lower case ``State`` is a data type describing the+operations which make up the ``STATE`` effect itself—we will go into+more detail about this in Section :ref:`sect-impleff`.++In this section, we will introduce some other supported effects,+allowing console I/O, exceptions, random number generation and+non-deterministic programming. For each effect we introduce, we will+begin with a summary of the effect, its supported operations, and the+contexts in which it may be used, like that above for ``STATE``, and+go on to present some simple examples. At the end, we will see some+examples of programs which combine multiple effects.++All of the effects in the library, including those described in this+section, are summarised in Appendix :ref:`sect-appendix`.++Console I/O+===========++Console I/O is supported with the ``STDIO``+effect, which allows reading and writing characters and strings to and+from standard input and standard output. Notice that there is a+constraint here on the computation context ``m``, because it only+makes sense to support console I/O operations in a context where we+can perform (or at the very least simulate) console I/O:++.. code-block:: idris++    module Effect.StdIO++    STDIO : EFFECT++    putChar  : Char ->   Eff () [STDIO]+    putStr   : String -> Eff () [STDIO]+    putStrLn : String -> Eff () [STDIO]++    getStr   :           Eff String [STDIO]+    getChar  :           Eff Char [STDIO]++    Handler StdIO IO where { ... }+    Handler StdIO (IOExcept a) where { ... }++Examples+--------++A program which reads the user’s name, then says hello, can be written+as follows:++.. code-block:: idris++    hello : Eff () [STDIO]+    hello = do putStr "Name? "+               x <- getStr+               putStrLn ("Hello " ++ trim x ++ "!")++We use ``trim`` here to remove the trailing newline from the+input. The resource associated with ``STDIO`` is simply the empty+tuple, which has a default value ``()``, so we can run this as+follows:++.. code-block:: idris++    main : IO ()+    main = run hello++In ``hello`` we could also use ``!``-notation instead of ``x <-+getStr``, since we only use the string that is read once:++.. code-block:: idris++    hello : Eff () [STDIO]+    hello = do putStr "Name? "+               putStrLn ("Hello " ++ trim !getStr ++ "!")++More interestingly, we can combine multiple effects in one+program. For example, we can loop, counting the number of people we’ve+said hello to:++.. code-block:: idris++    hello : Eff () [STATE Int, STDIO]+    hello = do putStr "Name? "+               putStrLn ("Hello " ++ trim !getStr ++ "!")+               update (+1)+               putStrLn ("I've said hello to: " ++ show !get ++ " people")+               hello++The list of effects given in ``hello`` means that the function can+call ``get`` and ``put`` on an integer state, and any functions which+read and write from the console. To run this, ``main`` does not need+to be changed.++Aside: Resource Types+---------------------++To find out the resource type of an effect, if necessary (for example+if we want to initialise a resource explicitly with ``runInit`` rather+than using a default value with ``run``) we can run the+``resourceType`` function at the REPL:++.. code-block:: idris++    *ConsoleIO> resourceType STDIO+    () : Type+    *ConsoleIO> resourceType (STATE Int)+    Int : Type++Exceptions+==========++The ``EXCEPTION``+effect is declared in module ``Effect.Exception``. This allows programs+to exit immediately with an error, or errors to be handled more+generally:++.. _eff-exception:+.. code-block:: idris++    module Effect.Exception++    EXCEPTION : Type -> EFFECT++    raise : a -> Eff b [EXCEPTION a]++    Handler (Exception a) Maybe where { ... }+    Handler (Exception a) List where { ... }+    Handler (Exception a) (Either a) where { ... }+    Handler (Exception a) (IOExcept a) where { ... }+    Show a => Handler (Exception a) IO where { ... }++Example+-------++Suppose we have a ``String`` which is expected to represent an integer+in the range ``0`` to ``n``. We can write a function ``parseNumber``+which returns an ``Int`` if parsing the string returns a number in the+appropriate range, or throws an exception otherwise. Exceptions are+parameterised by an error type:++.. code-block:: idris++    data Error = NotANumber | OutOfRange++    parseNumber : Int -> String -> Eff Int [EXCEPTION Error]+    parseNumber num str+       = if all isDigit (unpack str)+            then let x = cast str in+                 if (x >=0 && x <= num)+                    then pure x+                    else raise OutOfRange+            else raise NotANumber++Programs which support the ``EXCEPTION`` effect can be run in any+context which has some way of throwing errors, for example, we can run+``parseNumber`` in the ``Either Error`` context. It returns a value of+the form ``Right x`` if successful:++.. code-block:: idris++    *Exception> the (Either Error Int) $ run (parseNumber 42 "20")+    Right 20 : Either Error Int++Or ``Left e`` on failure, carrying the appropriate exception:++.. code-block:: idris++    *Exception> the (Either Error Int) $ run (parseNumber 42 "50")+    Left OutOfRange : Either Error Int++    *Exception> the (Either Error Int) $ run (parseNumber 42 "twenty")+    Left NotANumber : Either Error Int++In fact, we can do a little bit better with ``parseNumber``, and have+it return a *proof* that the integer is in the required range along+with the integer itself. One way to do this is define a type of+bounded integers, ``Bounded``:++.. code-block:: idris++    Bounded : Int -> Type+    Bounded x = (n : Int ** So (n >= 0 && n <= x))++Recall that ``So`` is parameterised by a ``Bool``, and only ``So+True`` is inhabited. We can use ``choose`` to construct such a value+from the result of a dynamic check:++.. code-block:: idris++    data So : Bool -> Type = Oh : So True++    choose : (b : Bool) -> Either (So b) (So (not b))++We then write ``parseNumber`` using ``choose`` rather than an+``if/then/else`` construct, passing the proof it returns on success as+the boundedness proof:++.. code-block:: idris++    parseNumber : (x : Int) -> String -> Eff (Bounded x) [EXCEPTION Error]+    parseNumber x str+       = if all isDigit (unpack str)+            then let num = cast str in+                 case choose (num >=0 && num <= x) of+                      Left p => pure (num ** p)+                      Right p => raise OutOfRange+            else raise NotANumber++Random Numbers+==============++Random number generation is also implemented by the library, in module+``Effect.Random``:++.. code-block:: idris++    module Effect.Random++    RND : EFFECT++    srand  : Integer ->            Eff () [RND]+    rndInt : Integer -> Integer -> Eff Integer [RND]+    rndFin : (k : Nat) ->          Eff (Fin (S k)) [RND]++    Handler Random m where { ... }++Random number generation is considered side-effecting because its+implementation generally relies on some external source of randomness.+The default implementation here relies on an integer *seed*, which can+be set with ``srand``. A specific seed will lead to a predictable,+repeatable sequence of random numbers. There are two functions which+produce a random number:++- ``rndInt``, which returns a random integer between the given lower+   and upper bounds.++- ``rndFin``, which returns a random element of a finite set+   (essentially a number with an upper bound given in its type).++Example+-------++We can use the ``RND`` effect to implement a simple guessing game. The+``guess`` function, given a target number, will repeatedly ask the+user for a guess, and state whether the guess is too high, too low, or+correct:++.. code-block:: idris++    guess : Int -> Eff () [STDIO]++For reference, the code for ``guess`` is given below:++.. _eff-game:+.. code-block:: idris++    guess : Int -> Eff () [STDIO]+    guess target+        = do putStr "Guess: "+             case run {m=Maybe} (parseNumber 100 (trim !getStr)) of+                  Nothing => do putStrLn "Invalid input"+                                guess target+                  Just (v ** _) =>+                             case compare v target of+                                 LT => do putStrLn "Too low"+                                          guess target+                                 EQ => putStrLn "You win!"+                                 GT => do putStrLn "Too high"+                                          guess target++Note that we use ``parseNumber`` as defined previously to read user input, but+we don’t need to list the ``EXCEPTION`` effect because we use a nested ``run``+to invoke ``parseNumber``, independently of the calling effectful program.++To invoke this, we pick a random number within the range 0–100,+having set up the random number generator with a seed, then run+``guess``:++.. code-block:: idris++    game : Eff () [RND, STDIO]+    game = do srand 123456789+              guess (fromInteger !(rndInt 0 100))++    main : IO ()+    main = run game++If no seed is given, it is set to the ``default`` value. For a less+predictable game, some better source of randomness would be required,+for example taking an initial seed from the system time. To see how to+do this, see the ``SYSTEM`` effect described in :ref:`sect-appendix`.+++Non-determinism+===============++The listing below gives the definition of the non-determinism+effect, which allows a program to choose a value non-deterministically+from a list of possibilities in such a way that the entire computation+succeeds:++.. code-block:: idris++    import Effects+    import Effect.Select++    SELECT : EFFECT++    select : List a -> Eff a [SELECT]++    Handler Selection Maybe where { ... }+    Handler Selection List where { ... }++Example+-------++The ``SELECT`` effect can be used to solve constraint problems, such+as finding Pythagorean triples. The idea is to use ``select`` to give+a set of candidate values, then throw an exception for any combination+of values which does not satisfy the constraint:++.. code-block:: idris++    triple : Int -> Eff (Int, Int, Int) [SELECT, EXCEPTION String]+    triple max = do z <- select [1..max]+                    y <- select [1..z]+                    x <- select [1..y]+                    if (x * x + y * y == z * z)+                       then pure (x, y, z)+                       else raise "No triple"++This program chooses a value for ``z`` between ``1`` and ``max``, then+values for ``y`` and ``x``. In operation, after a ``select``, the+program executes the rest of the ``do``-block for every possible+assignment, effectively searching depth-first. If the list is empty+(or an exception is thrown) execution fails.++There are handlers defined for ``Maybe`` and ``List`` contexts, i.e.+contexts which can capture failure. Depending on the context ``m``,+``triple`` will either return the first triple it finds (if in+``Maybe`` context) or all triples in the range (if in ``List``+context). We can try this as follows:++.. code-block:: idris++    main : IO ()+    main = do print $ the (Maybe _) $ run (triple 100)+              print $ the (List _) $ run (triple 100)++``vadd`` revisited+==================++We now return to the ``vadd`` program from the introduction. Recall the+definition:++.. code-block:: idris++    vadd : Vect n Int -> Vect n Int -> Vect n Int+    vadd []        []        = []+    vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys++Using , we can set up a program so that it reads input from a user,+checks that the input is valid (i.e both vectors contain integers, and+are the same length) and if so, pass it on to ``vadd``. First, we+write a wrapper for ``vadd`` which checks the lengths and throw an+exception if they are not equal. We can do this for input vectors of+length ``n`` and ``m`` by matching on the implicit arguments ``n`` and+``m`` and using ``decEq`` to produce a proof of their equality, if+they are equal:++.. code-block:: idris++    vadd_check : Vect n Int -> Vect m Int ->+                 Eff (Vect m Int) [EXCEPTION String]+    vadd_check {n} {m} xs ys with (decEq n m)+      vadd_check {n} {m=n} xs ys | (Yes Refl) = pure (vadd xs ys)+      vadd_check {n} {m}   xs ys | (No contra) = raise "Length mismatch"++To read a vector from the console, we implement a function of the+following type:++.. code-block:: idris++    read_vec : Eff (p ** Vect p Int) [STDIO]++This returns a dependent pair of a length, and a vector of that+length, because we cannot know in advance how many integers the user+is going to input. We can use ``-1`` to indicate the end of input:++.. code-block:: idris++    read_vec : Eff (p ** Vect p Int) [STDIO]+    read_vec = do putStr "Number (-1 when done): "+                  case run (parseNumber (trim !getStr)) of+                       Nothing => do putStrLn "Input error"+                                     read_vec+                       Just v => if (v /= -1)+                                    then do (_ ** xs) <- read_vec+                                            pure (_ ** v :: xs)+                                    else pure (_ ** [])+      where+        parseNumber : String -> Eff Int [EXCEPTION String]+        parseNumber str+          = if all (\x => isDigit x || x == '-') (unpack str)+               then pure (cast str)+               else raise "Not a number"++This uses a variation on ``parseNumber`` which does not require a+number to be within range.++Finally, we write a program which reads two vectors and prints the+result of pairwise addition of them, throwing an exception if the+inputs are of differing lengths:++.. code-block:: idris++    do_vadd : Eff () [STDIO, EXCEPTION String]+    do_vadd = do putStrLn "Vector 1"+                 (_ ** xs) <- read_vec+                 putStrLn "Vector 2"+                 (_ ** ys) <- read_vec+                 putStrLn (show !(vadd_check xs ys))++By having explicit lengths in the type, we can be sure that ``vadd``+is only being used where the lengths of inputs are guaranteed to be+equal.  This does not stop us reading vectors from user input, but it+does require that the lengths are checked and any discrepancy is dealt+with gracefully.+++Example: An Expression Calculator+=================================++To show how these effects can fit together, let us consider an+evaluator for a simple expression language, with addition and integer+values.++.. code-block:: idris++    data Expr = Val Integer+              | Add Expr Expr++An evaluator for this language always returns an ``Integer``, and+there are no situations in which it can fail!++.. code-block:: idris++    eval : Expr -> Integer+    eval (Val x) = x+    eval (Add l r) = eval l + eval r++If we add variables, however, things get more interesting. The+evaluator will need to be able to access the values stored in+variables, and variables may be undefined.++.. code-block:: idris++    data Expr = Val Integer+              | Var String+              | Add Expr Expr++To start, we will change the type of ``eval`` so that it is effectful,+and supports an exception effect for throwing errors, and a state+containing a mapping from variable names (as ``String``) to their+values:++.. code-block:: idris++    Env : Type+    Env = List (String, Integer)++    eval : Expr -> Eff Integer [EXCEPTION String, STATE Env]+    eval (Val x) = return x+    eval (Add l r) = return $ !(eval l) + !(eval r)++Note that we are using ``!``-notation to avoid having to bind+subexpressions in a ``do`` block. Next, we add a case for evaluating+``Var``:++.. code-block:: idris++    eval (Var x) = case lookup x !get of+                        Nothing => raise $ "No such variable " ++ x+                        Just val => return val++This retrieves the state (with ``get``, supported by the ``STATE Env``+effect) and raises an exception if the variable is not in the+environment (with ``raise``, supported by the ``EXCEPTION String``+effect).++To run the evaluator on a particular expression in a particular+environment of names and their values, we can write a function which+sets the state then invokes ``eval``:++.. code-block:: idris++    runEval : List (String, Integer) -> Expr -> Maybe Integer+    runEval args expr = run (eval' expr)+      where eval' : Expr -> Eff Integer [EXCEPTION String, STATE Env]+            eval' e = do put args+                         eval e++We have picked ``Maybe`` as a computation context here; it needs to be+a context which is available for every effect supported by+``eval``. In particular, because we have exceptions, it needs to be a+context which supports exceptions. Alternatively, ``Either String`` or+``IO`` would be fine, for example.++What if we want to extend the evaluator further, with random number+generation? To achieve this, we add a new constructor to ``Expr``,+which gives a random number up to a maximum value:++.. code-block:: idris++    data Expr = Val Integer+              | Var String+              | Add Expr Expr+              | Random Integer++Then, we need to deal with the new case, making sure that we extend+the list of events to include ``RND``. It doesn't matter where ``RND``+appears in the list, as long as it is present:++.. code-block:: idris++    eval : Expr -> Eff Integer [EXCEPTION String, RND, STATE Env]++    eval (Random upper) = rndInt 0 upper++For test purposes, we might also want to print the random number which+has been generated:++.. code-block:: idris++    eval (Random upper) = do val <- rndInt 0 upper+                             putStrLn (show val)+                             return val++If we try this without extending the effects list, we would see an+error something like the following:++::++    Expr.idr:28:6:When elaborating right hand side of eval:+    Can't solve goal+       SubList [STDIO]+               [(EXCEPTION String), RND, (STATE (List (String, Integer)))]++In other words, the ``STDIO`` effect is not available. We can correct+this simply by updating the type of ``eval`` to include ``STDIO``.++.. code-block:: idris++    eval : Expr -> Eff Integer [STDIO, EXCEPTION String, RND, STATE Env]++.. note:: Using ``STDIO`` will restrict the number of contexts in+          which ``eval`` can be ``run`` to those which support+          ``STDIO``, such as ``IO``. Once effect lists get longer, it+          can be a good idea instead to encapsulate sets of effects in+          a type synonym. This is achieved as follows, simply by+          defining a function which computes a type, since types are+          first class in Idris:++          .. code-block:: idris++              EvalEff : Type -> Type+              EvalEff t = Eff t [STDIO, EXCEPTION String, RND, STATE Env]++              eval : Expr -> EvalEff Integer
+ docs/effects/state.rst view
@@ -0,0 +1,529 @@+.. _sect-state:++*****+State+*****++Many programs, even pure programs, can benefit from locally mutable+state. For example, consider a program which tags binary tree nodes+with a counter, by an inorder traversal (i.e. counting depth first,+left to right). This would perform something like the following:++|image|++We can describe binary trees with the following data type ``BTree``+and ``testTree`` to represent the example input above:++.. code-block:: idris++    data BTree a = Leaf+                 | Node (BTree a) a (BTree a)++    testTree : BTree String+    testTree = Node (Node Leaf "Jim" Leaf)+                    "Fred"+                    (Node (Node Leaf "Alice" Leaf)+                          "Sheila"+                          (Node Leaf "Bob" Leaf))++Then our function to implement tagging, beginning to tag with a+specific value ``i``, has the following type:++.. code-block:: idris++    treeTag : (i : Int) -> BTree a -> BTree (Int, a)++First attempt+=============++Naïvely, we can implement ``treeTag`` by implementing a helper+function which propagates a counter, returning the result of the count+for each subtree:++.. code-block:: idris++    treeTagAux : (i : Int) -> BTree a -> (Int, BTree (Int, a))+    treeTagAux i Leaf = (i, Leaf)+    treeTagAux i (Node l x r)+           = let (i', l') = treeTagAux i l in+             let x' = (i', x) in+             let (i'', r') = treeTagAux (i' + 1) r in+                 (i'', Node l' x' r')++    treeTag : (i : Int) -> BTree a -> BTree (Int, a)+    treeTag i x = snd (treeTagAux i x)++This gives the expected result when run at the REPL prompt:++.. code-block:: idris++    *TreeTag> treeTag 1 testTree+    Node (Node Leaf (1, "Jim") Leaf)+         (2, "Fred")+         (Node (Node Leaf (3, "Alice") Leaf)+               (4, "Sheila")+               (Node Leaf (5, "Bob") Leaf)) : BTree (Int, String)++This works as required, but there are several problems when we try to+scale this to larger programs. It is error prone, because we need to+ensure that state is propagated correctly to the recursive calls (i.e.+passing the appropriate ``i`` or ``i’``). It is hard to read, because+the functional details are obscured by the state propagation. Perhaps+most importantly, there is a common programming pattern here which+should be abstracted but instead has been implemented by hand. There+is local mutable state (the counter) which we have had to make+explicit.++Introducing ``Effects``+=======================++Idris provides a library, ``Effects`` [3]_, which captures this+pattern and many others involving effectful computation [1]_. An+effectful program ``f`` has a type of the following form:++.. code-block:: idris++    f : (x1 : a1) -> (x2 : a2) -> ... -> Eff t effs++That is, the return type gives the effects that ``f`` supports+(``effs``, of type ``List EFFECT``) and the type the computation+returns ``t``. So, our ``treeTagAux`` helper could be written with the+following type:++.. code-block:: idris++    treeTagAux : BTree a -> Eff (BTree (Int, a)) [STATE Int]++That is, ``treeTagAux`` has access to an integer state, because the+list of available effects includes ``STATE Int``. ``STATE`` is+declared as follows in the module ``Effect.State`` (that is, we must+``import Effect.State`` to be able to use it):++.. code-block:: idris++    STATE : Type -> EFFECT++It is an effect parameterised by a type (by convention, we write+effects in all capitals). The ``treeTagAux`` function is an effectful+program which builds a new tree tagged with ``Ints``, and is+implemented as follows:++.. code-block:: idris++    treeTagAux Leaf = pure Leaf+    treeTagAux (Node l x r)+        = do l' <- treeTagAux l+             i <- get+             put (i + 1)+             r' <- treeTagAux r+             pure (Node l' (i, x) r')++There are several remarks to be made about this implementation.+Essentially, it hides the state, which can be accessed using ``get``+and updated using ``put``, but it introduces several new features.+Specifically, it uses ``do``-notation, binding variables with ``<-``,+and a ``pure`` function. There is much to be said about these+features, but for our purposes, it suffices to know the following:++- ``do`` blocks allow effectful operations to be sequenced.++- ``x <- e`` binds the result of an effectful operation ``e`` to a+   variable ``x``. For example, in the above code, ``treeTagAux l`` is+   an effectful operation returning ``BTree (Int, a)``, so ``l’`` has+   type ``BTree (Int, a)``.++- ``pure e`` turns a pure value ``e`` into the result of an effectful+   operation.++The ``get`` and ``put`` functions read and write a state ``t``,+assuming that the ``STATE t`` effect is available. They have the+following types, polymorphic in the state ``t`` they manage:++.. code-block:: idris++    get :      Eff t [STATE t]+    put : t -> Eff () [STATE t]++A program in ``Eff`` can call any other function in ``Eff`` provided+that the calling function supports at least the effects required by+the called function. In this case, it is valid for ``treeTagAux`` to+call both ``get`` and ``put`` because all three functions support the+``STATE Int`` effect.++Programs in ``Eff`` are run in some underlying *computation context*,+using the ``run`` or ``runPure`` function. Using ``runPure``, which+runs an effectful program in the identity context, we can write the+``treeTag`` function as follows, using ``put`` to initialise the+state:++.. code-block:: idris++    treeTag : (i : Int) -> BTree a -> BTree (Int, a)+    treeTag i x = runPure (do put i+                              treeTagAux x)++We could also run the program in an impure context such as ``IO``,+without changing the definition of ``treeTagAux``, by using ``run``+instead of ``runPure``:++.. code-block:: idris++    treeTagAux : BTree a -> Eff (BTree (Int, a)) [STATE Int]+    ...++    treeTag : (i : Int) -> BTree a -> IO (BTree (Int, a))+    treeTag i x = run (do put i+                          treeTagAux x)++Note that the definition of ``treeTagAux`` is exactly as before. For+reference, this complete program (including a ``main`` to run it) is+shown in Listing [introprog].++.. code-block:: idris++    module Main++    import Effects+    import Effect.State++    data BTree a = Leaf+                 | Node (BTree a) a (BTree a)++    Show a => Show (BTree a) where+        show Leaf = "[]"+        show (Node l x r) = "[" ++ show l ++ " "+                                ++ show x ++ " "+                                ++ show r ++ "]"++    testTree : BTree String+    testTree = Node (Node Leaf "Jim" Leaf)+                  "Fred"+                  (Node (Node Leaf "Alice" Leaf)+                        "Sheila"+                        (Node Leaf "Bob" Leaf))++    treeTagAux : BTree a -> Eff (BTree (Int, a)) [STATE Int]+    treeTagAux Leaf = pure Leaf+    treeTagAux (Node l x r) = do l' <- treeTagAux l+                                 i <- get+                                 put (i + 1)+                                 r' <- treeTagAux r+                                 pure (Node l' (i, x) r')++    treeTag : (i : Int) -> BTree a -> BTree (Int, a)+    treeTag i x = runPure (do put i; treeTagAux x)++    main : IO ()+    main = print (treeTag 1 testTree)++Effects and Resources+=====================++Each effect is associated with a *resource*, which is initialised+before an effectful program can be run. For example, in the case of+``STATE Int`` the corresponding resource is the integer state itself.+The types of ``runPure`` and ``run`` show this (slightly simplified+here for illustrative purposes):++.. code-block:: idris++    runPure : {env : Env id xs} -> Eff a xs -> a+    run : Applicative m => {env : Env m xs} -> Eff a xs -> m a++The ``env`` argument is implicit, and initialised automatically where+possible using default values given by implementations of the following +interface:++.. code-block:: idris++    interface Default a where+        default : a++Implementations of ``Default`` are defined for all primitive types, and many+library types such as ``List``, ``Vect``, ``Maybe``, pairs, etc.+However, where no default value exists for a resource type (for+example, you may want a ``STATE`` type for which there is no+``Default`` implementation) the resource environment can be given explicitly+using one of the following functions:++.. code-block:: idris++    runPureInit : Env id xs -> Eff a xs -> a+    runInit : Applicative m => Env m xs -> Eff a xs -> m a++To be well-typed, the environment must contain resources corresponding+exactly to the effects in ``xs``. For example, we could also have+implemented ``treeTag`` by initialising the state as follows:++.. code-block:: idris++    treeTag : (i : Int) -> BTree a -> BTree (Int, a)+    treeTag i x = runPureInit [i] (treeTagAux x)++Labelled Effects+================++What if we have more than one state, especially more than one state of+the same type? How would ``get`` and ``put`` know which state they+should be referring to? For example, how could we extend the tree+tagging example such that it additionally counts the number of leaves+in the tree? One possibility would be to change the state so that it+captured both of these values, e.g.:++.. code-block:: idris++    treeTagAux : BTree a -> Eff (BTree (Int, a)) [STATE (Int, Int)]++Doing this, however, ties the two states together throughout (as well+as not indicating which integer is which). It would be nice to be able+to call effectful programs which guaranteed only to access one of the+states, for example. In a larger application, this becomes+particularly important.++The library therefore allows effects in general to be *labelled* so+that they can be referred to explicitly by a particular name. This+allows multiple effects of the same type to be included. We can count+leaves and update the tag separately, by labelling them as follows:++.. code-block:: idris++    treeTagAux : BTree a ->  Eff (BTree (Int, a))+                                   ['Tag ::: STATE Int,+                                    'Leaves ::: STATE Int]++The ``:::`` operator allows an arbitrary label to be given to an+effect.  This label can be any type—it is simply used to identify an+effect uniquely. Here, we have used a symbol type. In general+``’name`` introduces a new symbol, the only purpose of which is to+disambiguate values [2]_.++When an effect is labelled, its operations are also labelled using the+``:-`` operator. In this way, we can say explicitly which state we+mean when using ``get`` and ``put``. The tree tagging program which+also counts leaves can be written as follows:++.. code-block:: idris++    treeTagAux Leaf = do+        'Leaves :- update (+1)+        pure Leaf+    treeTagAux (Node l x r) = do+        l' <- treeTagAux l+        i <- 'Tag :- get+        'Tag :- put (i + 1)+        r' <- treeTagAux r+        pure (Node l' (i, x) r')++The ``update`` function here is a combination of ``get`` and ``put``,+applying a function to the current state.++.. code-block:: idris++    update : (x -> x) -> Eff () [STATE x]++Finally, our top level ``treeTag`` function now returns a pair of the+number of leaves, and the new tree. Resources for labelled effects are+initialised using the ``:=`` operator (reminiscent of assignment in an+imperative language):++.. code-block:: idris++    treeTag : (i : Int) -> BTree a -> (Int, BTree (Int, a))+    treeTag i x = runPureInit ['Tag := i, 'Leaves := 0]+                        (do x' <- treeTagAux x+                            leaves <- 'Leaves :- get+                            pure (leaves, x'))++To summarise, we have:++- ``:::`` to convert an effect to a labelled effect.++- ``:-`` to convert an effectful operation to a labelled effectful operation.++- ``:=`` to initialise a resource for a labelled effect.++Or, more formally with their types (slightly simplified to account+only for the situation where available effects are not updated):++.. code-block:: idris++    (:::) : lbl -> EFFECT -> EFFECT+    (:-)  : (l : lbl) -> Eff a [x] -> Eff a [l ::: x]+    (:=)  : (l : lbl) -> res -> LRes l res++Here, ``LRes`` is simply the resource type associated with a labelled+effect. Note that labels are polymorphic in the label type ``lbl``.+Hence, a label can be anything—a string, an integer, a type, etc.++``!``-notation+==============++In many cases, using ``do``-notation can make programs unnecessarily+verbose, particularly in cases where the value bound is used once,+immediately. The following program returns the length of the+``String`` stored in the state, for example:++.. code-block:: idris++    stateLength : Eff Nat [STATE String]+    stateLength = do x <- get+                     pure (length x)++This seems unnecessarily verbose, and it would be nice to program in a+more direct style in these cases. provides ``!``-notation to help with+this. The above program can be written instead as:++.. code-block:: idris++    stateLength : Eff Nat [STATE String]+    stateLength = pure (length !get)++The notation ``!expr`` means that the expression ``expr`` should be+evaluated and then implicitly bound. Conceptually, we can think of+``!`` as being a prefix function with the following type:++.. code-block:: idris++    (!) : Eff a xs -> a++Note, however, that it is not really a function, merely syntax! In+practice, a subexpression ``!expr`` will lift ``expr`` as high as+possible within its current scope, bind it to a fresh name ``x``, and+replace ``!expr`` with ``x``. Expressions are lifted depth first, left+to right. In practice, ``!``-notation allows us to program in a more+direct style, while still giving a notational clue as to which+expressions are effectful.++For example, the expression:++.. code-block:: idris++    let y = 42 in f !(g !(print y) !x)++is lifted to:++.. code-block:: idris++    let y = 42 in do y' <- print y+                     x' <- x+                     g' <- g y' x'+                     f g'++The Type ``Eff``+================++Underneath, ``Eff`` is an overloaded function which translates to an+underlying type ``EffM``:++.. code-block:: idris++    EffM : (m : Type -> Type) -> (t : Type)+            -> (List EFFECT)+            -> (t -> List EFFECT) -> Type++This is more general than the types we have been writing so far. It is+parameterised over an underlying computation context ``m``, a+result type ``t`` as we have already seen, as well as a ``List EFFECT`` and a+function type ``t -> List EFFECT``.++These additional parameters are the list of *input* effects, and a+list of *output* effects, computed from the result of an effectful+operation.  That is: running an effectful program can change the set+of effects available! This is a particularly powerful idea, and we+will see its consequences in more detail later. Some examples of+operations which can change the set of available effects are:++- Updating a state containing a dependent type (for example adding an element to a vector).++- Opening a file for reading is an effect, but whether the file really+  *is* open afterwards depends on whether the file was successfully+  opened.++- Closing a file means that reading from the file should no longer be+  possible.++While powerful, this can make uses of the ``EffM`` type hard to read.+Therefore the library provides an overloaded function ``Eff``+There are the following three versions:++.. code-block:: idris++    SimpleEff.Eff : (t : Type) -> (input_effs : List EFFECT) -> Type+    TransEff.Eff  : (t : Type) -> (input_effs : List EFFECT) ->+                                  (output_effs : List EFFECT) -> Type+    DepEff.Eff    : (t : Type) -> (input_effs : List EFFECT) ->+                                  (output_effs_fn : x -> List EFFECT) -> Type++So far, we have used only the first version, ``SimpleEff.Eff``, which+is defined as follows:++.. code-block:: idris++    Eff : (x : Type) -> (es : List EFFECT) -> Type+    Eff x es = {m : Type -> Type} -> EffM m x es (\v => es)++i.e. the set of effects remains the same on output. This suffices for+the ``STATE`` example we have seen so far, and for many useful+side-effecting programs. We could also have written ``treeTagAux``+with the expanded type:++.. code-block:: idris++    treeTagAux : BTree a ->+                 EffM m (BTree (Int, a)) [STATE Int] (\x => [STATE Int])++Later, we will see programs which update effects:++.. code-block:: idris++    Eff a xs xs'++which is expanded to++.. code-block:: idris++    EffM m a xs (\_ => xs')++i.e. the set of effects is updated to ``xs’`` (think of a transition+in a state machine). There is, for example, a version of ``put`` which+updates the type of the state:++.. code-block:: idris++    putM : y -> Eff () [STATE x] [STATE y]++Also, we have:++.. code-block:: idris++    Eff t xs (\res => xs')++which is expanded to++.. code-block:: idris++    EffM m t xs (\res => xs')++i.e. the set of effects is updated according to the result of the+operation ``res``, of type ``t``.++Parameterising ``EffM`` over an underlying computation context allows us+to write effectful programs which are specific to one context, and in some+cases to write programs which *extend* the list of effects available using+the ``new`` function, though this is beyond the scope of this tutorial.++.. [1] The earlier paper [3]_ describes the essential implementation+   details, although the library presented there is an earlier version+   which is less powerful than that presented in this tutorial.++.. [2] In practice, ``’name`` simply introduces a new empty type++.. [3] Edwin Brady. 2013. Programming and reasoning with algebraic+       effects and dependent types. SIGPLAN Not. 48, 9 (September+       2013), 133-144. DOI=10.1145/2544174.2500581+       http://dl.acm.org/citation.cfm?doid=2544174.2500581++++.. |image| image:: ../image/effects-tree.png+                   :width: 500px
+ docs/effects/summary.rst view
@@ -0,0 +1,152 @@+.. _sect-appendix:++***************+Effects Summary+***************++This appendix gives interfaces for the core effects provided by the+library.++EXCEPTION+=========++.. code-block:: idris++    module Effect.Exception++    import Effects+    import System+    import Control.IOExcept++    EXCEPTION : Type -> EFFECT++    raise : a -> Eff b [EXCEPTION a]++    Handler (Exception a) Maybe where { ... }+    Handler (Exception a) List where { ... }+    Handler (Exception a) (Either a) where { ... }+    Handler (Exception a) (IOExcept a) where { ... }+    Show a => Handler (Exception a) IO where { ... }++FILE\_IO+========++.. code-block:: idris++    module Effect.File++    import Effects+    import Control.IOExcept++    FILE_IO : Type -> EFFECT++    data OpenFile : Mode -> Type++    open : (fname : String)+           -> (m : Mode)+           -> Eff Bool [FILE_IO ()] +                       (\res => [FILE_IO (case res of+                                               True => OpenFile m+                                               False => ())])+    close : Eff () [FILE_IO (OpenFile m)] [FILE_IO ()]++    readLine  : Eff String [FILE_IO (OpenFile Read)]+    writeLine : String -> Eff () [FILE_IO (OpenFile Write)]+    eof       : Eff Bool [FILE_IO (OpenFile Read)]++    Handler FileIO IO where { ... }++RND+===++.. code-block:: idris++    module Effect.Random++    import Effects+    import Data.Vect+    import Data.Fin++    RND : EFFECT++    srand  : Integer ->            Eff m () [RND]+    rndInt : Integer -> Integer -> Eff m Integer [RND]+    rndFin : (k : Nat) ->          Eff m (Fin (S k)) [RND]++    Handler Random m where { ... }++SELECT+======++.. code-block:: idris++    module Effect.Select++    import Effects++    SELECT : EFFECT++    select : List a -> Eff m a [SELECT]++    Handler Selection Maybe where { ... }+    Handler Selection List where { ... }++STATE+=====++.. code-block:: idris++    module Effect.State++    import Effects++    STATE : Type -> EFFECT++    get    :             Eff m x [STATE x]+    put    : x ->        Eff m () [STATE x]+    putM   : y ->        Eff m () [STATE x] [STATE y]+    update : (x -> x) -> Eff m () [STATE x]++    Handler State m where { ... }++STDIO+=====++.. code-block:: idris++    module Effect.StdIO++    import Effects+    import Control.IOExcept++    STDIO : EFFECT++    putChar  : Handler StdIO m => Char ->   Eff m () [STDIO]+    putStr   : Handler StdIO m => String -> Eff m () [STDIO]+    putStrLn : Handler StdIO m => String -> Eff m () [STDIO]++    getStr   : Handler StdIO m =>           Eff m String [STDIO]+    getChar  : Handler StdIO m =>           Eff m Char [STDIO]++    Handler StdIO IO where { ... }+    Handler StdIO (IOExcept a) where { ... }++SYSTEM+======++.. code-block:: idris++    module Effect.System++    import Effects+    import System+    import Control.IOExcept++    SYSTEM : EFFECT++    getArgs : Handler System e =>           Eff e (List String) [SYSTEM]+    time    : Handler System e =>           Eff e Int [SYSTEM]+    getEnv  : Handler System e => String -> Eff e (Maybe String) [SYSTEM]++    Handler System IO where { ... }+    Handler System (IOExcept a) where { ... }
+ docs/faq/faq.rst view
@@ -0,0 +1,291 @@+**************************+Frequently Asked Questions+**************************++What are the differences between Agda and Idris?+================================================++Like Idris, Agda is a functional language with dependent types, supporting+dependent pattern matching. Both can be used for writing programs and proofs.+However, Idris has been designed from the start to emphasise general purpose+programming rather than theorem proving. As such, it supports interoperability+with systems libraries and C programs, and language constructs for+domain specific language implementation. It also includes higher level+programming constructs such as interfaces (similar to type classes) and do notation.++Idris supports multiple back ends (C and JavaScript by default, with the+ability to add more via plugins) and has a reference run time system, written+in C, with a garbage collector and built-in message passing concurrency.+++Is Idris production ready?+==========================++Idris is primarily a research tool for exploring the possibilities of software+development with dependent types, meaning that the primary goal is not (yet) to+make a system which could be used in production. As such, there are a few rough+corners, and lots of missing libraries. Nobody is working on Idris full time,+and we don't have the resources at the moment to polish the system on our own.+Therefore, we don't recommend building your business around it!++Having said that, contributions which help towards making Idris suitable+for use in production would be very welcome - this includes (but is not+limited to) extra library support, polishing the run-time system (and ensuring+it is robust), providing and maintaining a JVM back end, etc.+++Why does Idris use eager evaluation rather than lazy?+=====================================================++Idris uses eager evaluation for more predictable performance, in particular+because one of the longer term goals is to be able to write efficient and+verified low level code such as device drivers and network infrastructure.+Furthermore, the Idris type system allows us to state precisely the type+of each value, and therefore the run-time form of each value. In a lazy+language, consider a value of type ``Int``:++.. code-block:: idris++    thing : Int++What is the representation of ``thing`` at run-time? Is it a bit pattern+representing an integer, or is it a pointer to some code which will compute+an integer? In Idris, we have decided that we would like to make this+distinction precise, in the type:++.. code-block:: idris++    thing_val : Int+    thing_comp : Lazy Int++Here, it is clear from the type that ``thing_val`` is guaranteed to be a+concrete ``Int``, whereas ``thing_comp`` is a computation which will produce an+``Int``.+++How can I make lazy control structures?+=======================================++You can make control structures using the special Lazy type. For+example, ``if...then...else...`` in Idris expands to an application of+a function named ``ifThenElse``. The default implementation for+Booleans is defined as follows in the library:++.. code-block:: idris++    ifThenElse : Bool -> (t : Lazy a) -> (e : Lazy a) -> a+    ifThenElse True  t e = t+    ifThenElse False t e = e++The type ``Lazy a`` for ``t`` and ``e`` indicates that those arguments will+only be evaluated if they are used, that is, they are evaluated lazily.+++Evaluation at the REPL doesn't behave as I expect. What's going on?+===================================================================++Being a fully dependently typed language, Idris has two phases where it+evaluates things, compile-time and run-time. At compile-time it will only+evaluate things which it knows to be total (i.e. terminating and covering all+possible inputs) in order to keep type checking decidable. The compile-time+evaluator is part of the Idris kernel, and is implemented in Haskell using a+HOAS (higher order abstract syntax) style representation of values. Since+everything is known to have a normal form here, the evaluation strategy doesn't+actually matter because either way it will get the same answer, and in practice+it will do whatever the Haskell run-time system chooses to do.++The REPL, for convenience, uses the compile-time notion of evaluation. As well+as being easier to implement (because we have the evaluator available) this can+be very useful to show how terms evaluate in the type checker. So you can see+the difference between:++.. code-block:: idris++    Idris> \n, m => (S n) + m+    \n => \m => S (plus n m) : Nat -> Nat -> Nat++    Idris> \n, m => n + (S m)+    \n => \m => plus n (S m) : Nat -> Nat -> Nat+++Why can't I use a function with no arguments in a type?+=======================================================++If you use a name in a type which begins with a lower case letter, and which is+not applied to any arguments, then Idris will treat it as an implicitly+bound argument. For example:++.. code-block:: idris++    append : Vect n ty -> Vect m ty -> Vect (n + m) ty++Here, ``n``, ``m``, and ``ty`` are implicitly bound. This rule applies even+if there are functions defined elsewhere with any of these names. For example,+you may also have:++.. code-block:: idris++    ty : Type+    ty = String++Even in this case, ``ty`` is still considered implicitly bound in the definition+of ``append``, rather than making the type of ``append`` equivalent to...++.. code-block:: idris++    append : Vect n String -> Vect m String -> Vect (n + m) String++...which is probably not what was intended!  The reason for this rule is so+that it is clear just from looking at the type of ``append``, and no other+context, what the implicitly bound names are. ++If you want to use an unapplied name in a type, you have two options. You+can either explicitly qualify it, for example, if ``ty`` is defined in the+namespace ``Main`` you can do the following:++.. code-block:: idris++    append : Vect n Main.ty -> Vect m Main.ty -> Vect (n + m) Main.ty++Alternatively, you can use a name which does not begin with a lower case+letter, which will never be implicitly bound:+    +.. code-block:: idris++    Ty : Type+    Ty = String++    append : Vect n Ty -> Vect m Ty -> Vect (n + m) Ty++As a convention, if a name is intended to be used as a type synonym, it is+best for it to begin with a capital letter to avoid this restriction.+++I have an obviously terminating program, but Idris says it possibly isn't total. Why is that?+=============================================================================================++Idris can't decide in general whether a program is terminating due to+the undecidability of the `Halting Problem+<https://en.wikipedia.org/wiki/Halting_problem>`_. It is possible, however,+to identify some programs which are definitely terminating. Idris does this+using "size change termination" which looks for recursive paths from a+function back to itself. On such a path, there must be at least one+argument which converges to a base case.++- Mutually recursive functions are supported+- However, all functions on the path must be fully applied. In particular,+  higher order applications are not supported+- Idris identifies arguments which converge to a base case by looking for+  recursive calls to syntactically smaller arguments of inputs. e.g.+  ``k`` is syntactically smaller than ``S (S k)`` because ``k`` is a+  subterm of ``S (S k)``, but ``(k, k)`` is+  not syntactically smaller than ``(S k, S k)``.++If you have a function which you believe to be terminating, but Idris does+not, you can either restructure the program, or use the ``assert_total``+function.+++When will Idris be self-hosting?+================================++It’s not a priority, though not a bad idea in the long run. It would be a+worthwhile effort in the short term to implement libraries to support+self-hosting, such as a good parsing library.+++Does Idris have universe polymorphism? What is the type of ``Type``?+====================================================================++Rather than universe polymorphism, Idris has a cumulative hierarchy of+universes; ``Type : Type 1``, ``Type 1 : Type 2``, etc.+Cumulativity means that if ``x : Type n`` and ``n <= m``, then+``x : Type m``. Universe levels are always inferred by Idris, and+cannot be specified explicitly. The REPL command ``:type Type 1`` will+result in an error, as will attempting to specify the universe level+of any type.+++Why does Idris use ``Double`` instead of ``Float64``?+=====================================================++Historically the C language and many other languages have used the+names ``Float`` and ``Double`` to represent floating point numbers of+size 32 and 64 respectively.  Newer languages such as Rust and Julia+have begun to follow the naming scheme described in `IEEE Standard for+Floating-Point Arithmetic (IEEE 754)+<https://en.wikipedia.org/wiki/IEEE_floating_point>`_. This describes+single and double precision numbers as ``Float32`` and ``Float64``;+the size is described in the type name.++Due to developer familiarity with the older naming convention, and+choice by the developers of Idris, Idris uses the C style convention.+That is, the name ``Double`` is used to describe double precision+numbers, and Idris does not support 32 bit floats at present.+++What is -ffreestanding?+=======================++The freestanding flag is used to build Idris binaries which have their+libs and compiler in a relative path. This is useful for building binaries+where the install directory is unknown at build time. When passing this+flag, the IDRIS_LIB_DIR environment variable needs to be set to the path+where the Idris libs reside relative to the idris executable. The+IDRIS_TOOLCHAIN_DIR environment variable is optional, if that is set,+Idris will use that path to find the C compiler.++Example::++   IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make+++What does the name ‘Idris’ mean?+================================++British people of a certain age may be familiar with this+`singing dragon <https://www.youtube.com/watch?v=G5ZMNyscPcg>`_. If+that doesn’t help, maybe you can invent a suitable acronym :-) .+++Will there be support for Unicode characters for operators?+===========================================================++There are several reasons why we should not support Unicode operators:++- It's hard to type (this is important if you're using someone else's code, for+  example). Various editors have their own input methods, but you have to know+  what they are.+- Not every piece of software easily supports it. Rendering issues have been+  noted on some mobile email clients, terminal-based IRC clients, web browsers,+  etc. There are ways to resolve these rendering issues but they provide a+  barrier to entry to using Idris.+- Even if we leave it out of the standard library (which we will in any case!)+  as soon as people start using it in their library code, others have to deal+  with it.+- Too many characters look too similar. We had enough trouble with confusion+  between 0 and O without worrying about all the different kinds of colons and+  brackets.+- There seems to be a tendency to go over the top with use of Unicode. For+  example, using sharp and flat for delay and force (or is it the other way+  around?) in Agda seems gratuitous. We don't want to encourage this sort of+  thing, when words are often better.++With care, Unicode operators can make things look pretty but so can ``lhs2TeX``.+Perhaps in a few years time things will be different and software will cope+better and it will make sense to revisit this. For now, however, Idris will not+be offering arbitrary Unicode symbols in operators.++This seems like an instance of `Wadler's+Law <http://www.haskell.org/haskellwiki/Wadler%27s_Law>`__ in action.++This answer is based on Edwin Brady's response in the following+`pull request <https://github.com/idris-lang/Idris-dev/pull/694#issuecomment-29559291>`__.+++Where can I find more answers?+==============================++There is an `Unofficial FAQ+<https://github.com/idris-lang/Idris-dev/wiki/Unofficial-FAQ>`_ on the wiki on+GitHub which answers more technical questions and may be updated more often.
+ docs/faq/index.rst view
@@ -0,0 +1,19 @@+.. _faq-index:++##########################+Frequently Asked Questions+##########################++.. note::+   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/+++.. toctree::+   :maxdepth: 1++   faq
+ docs/guides/index.rst view
@@ -0,0 +1,22 @@+.. _guides-index:++################################+Tutorials on the Idris Language+################################++Tutorials submitted by community members.++.. note::+   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/+++.. toctree::+   :maxdepth: 1++   type-providers-ffi+   theorem-prover
+ docs/guides/theorem-prover.rst view
@@ -0,0 +1,217 @@+*******************************+The Interactive Theorem Prover+*******************************++This short guide contributed by a community member illustrates how to prove associativity of addition on ``Nat`` using the interactive theorem prover.++First we define a module ``Foo.idr``++.. code-block:: idris++    module Foo++    plusAssoc : plus n (plus m o) = plus (plus n m) o+    plusAssoc = ?rhs++We wish to perform induction on ``n``. First we load the file into the Idris ``REPL`` as follows::++    $ idris Foo.idr++We will be given the following prompt, in future releases the version string will differ::++         ____    __     _+        /  _/___/ /____(_)____+        / // __  / ___/ / ___/     Version 0.9.18.1+      _/ // /_/ / /  / (__  )      http://www.idris-lang.org/+     /___/\__,_/_/  /_/____/       Type :? for help++    Idris is free software with ABSOLUTELY NO WARRANTY.+    For details type :warranty.+    Type checking ./Foo.idr+    Metavariables: Foo.rhs+    *Foo>+++Explore the Context+====================++We start the interactive session by asking Idris to prove the+hole ``rhs`` using the command ``:p rhs``. Idris by default+will show us the initial context. This looks as follows::++    *Foo> :p rhs+    ----------                 Goal:                  ----------+    { hole 0 }:+     (n : Nat) ->+     (m : Nat) ->+     (o : Nat) ->+     plus n (plus m o) = plus (plus n m) o++Application of Intros+=====================++We first apply the ``intros`` tactic::++    -Foo.rhs> intros+    ----------              Other goals:              ----------+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+    ----------                 Goal:                  ----------+    { hole 3 }:+     plus n (plus m o) = plus (plus n m) o++Induction on ``n``+==================++Then apply ``induction`` on to ``n``::++    -Foo.rhs> induction n+    ----------              Other goals:              ----------+    elim_S0+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+    ----------                 Goal:                  ----------+    elim_Z0:+     plus Z (plus m o) = plus (plus Z m) o+++Compute+=======++::++    -Foo.rhs> compute+    ----------              Other goals:              ----------+    elim_S0+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+    ----------                 Goal:                  ----------+    elim_Z0:+     plus m o = plus m o++Trivial+=======++::++    -Foo.rhs> trivial+    ----------              Other goals:              ----------+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+    ----------                 Goal:                  ----------+    elim_S0:+     (n__0 : Nat) ->+     (plus n__0 (plus m o) = plus (plus n__0 m) o) ->+     plus (S n__0) (plus m o) = plus (plus (S n__0) m) o++Intros+======++::++    -Foo.rhs> intros+    ----------              Other goals:              ----------+    { hole 4 }+    elim_S0+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+     n__0 : Nat+     ihn__0 : plus n__0 (plus m o) = plus (plus n__0 m) o+    ----------                 Goal:                  ----------+    { hole 5 }:+     plus (S n__0) (plus m o) = plus (plus (S n__0) m) o+++Compute+=======++::++    -Foo.rhs> compute+    ----------              Other goals:              ----------+    { hole 4 }+    elim_S0+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+     n__0 : Nat+     ihn__0 : plus n__0 (plus m o) = plus (plus n__0 m) o+    ----------                 Goal:                  ----------+    { hole 5 }:+     S (plus n__0 (plus m o)) = S (plus (plus n__0 m) o)+++Rewrite+=======++::++    -Foo.rhs> rewrite ihn__0+    ----------              Other goals:              ----------+    { hole 5 }+    { hole 4 }+    elim_S0+    { hole 2 }+    { hole 1 }+    { hole 0 }+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+     o : Nat+     n__0 : Nat+     ihn__0 : plus n__0 (plus m o) = plus (plus n__0 m) o+    ----------                 Goal:                  ----------+    { hole 6 }:+     S (plus n__0 (plus m o)) = S (plus n__0 (plus m o))++Trivial+=======++::++    -Foo.rhs> trivial+    rhs: No more goals.+    -Foo.rhs> qed+    Proof completed!+    Foo.rhs = proof+      intros+      induction n+      compute+      trivial+      intros+      compute+      rewrite ihn__0+      trivial++Two goals were created: one for ``Z`` and one for ``S``.+Here we have proven associativity, and assembled a tactic based proof script.+This proof script can be added to ``Foo.idr``.
+ docs/guides/type-providers-ffi.rst view
@@ -0,0 +1,245 @@+***********************+Type Providers in Idris+***********************++`Type providers in Idris+<http://www.itu.dk/people/drc/pubs/dependent-type-providers.pdf>`__+are simple enough, but there are a few caveats to using them that it+would be worthwhile to go through the basic steps. We also go over+foreign functions, because these will often be used with type+providers.++The use case+============++First, let's talk about *why* we might want type providers. There are+a number of reasons to use them and there are other examples available+around the net, but in this tutorial we'll be using them to port C's+``struct stat`` to Idris.++Why do we need type providers? Well, Idris's FFI needs to know the+types of the things it passes to and from C, but the fields of a+``struct stat`` are implementation-dependent types that cannot be+relied upon. We don't just want to hard-code these types into our+program... so we'll use a type provider to find them at compile time!++A simple example+================++First, let's go over a basic usage of type providers, because foreign+functions can be confusing but it's important to remember that+providers themselves are simple.++A type provider is simply an IO action that returns a value of this+type:++.. code-block:: idris++    data Provider a = Provide a | Error String++Looks familiar? ``Provider`` is just ``Either a String``, given a+slightly more descriptive name.++Remember though, type providers we use in our program must be IO+actions. Let's write a simple one now:++.. code-block:: idris++    module Provider+    -- Asks nicely for the user to supply the size of C's size_t type on this+    -- machine+    getSizeT : IO (Provider Int)+    getSizeT = do+      putStrLn "I'm sorry, I don't know how big size_t is. Can you tell me, in bytes?"+      resp <- getLine+      case readInt resp of+         Just sizeTSize => return (Provide sizeTSize)+         Nothing => return (Error "I'm sorry, I don't understand.")+    -- the readInt function is left as an exercise++We assume that whoever's compiling the library knows the size of+``size_t``, so we'll just ask them! (Don't worry, we'll get it+ourselves later.) Then, if their response can be converted to an+integer, we present ``Provide sizeTSize`` as the result of our IO+action; or if it can't, we signal a failure. (This will then become a+compile-time error.)++Now we can use this IO action as a type provider:++.. code-block:: idris++    module Main+    -- to gain access to the IO action we're using as a provider+    import Provider++    -- TypeProviders is an extension, so we'll enable it+    %language TypeProviders++    -- And finally, use the provider!+    -- Note that the parentheses are mandatory.+    %provide (sizeTSize : Int) with getSizeT++    -- From now on it's just a normal program where `sizeTSize` is available+    -- as a top-level constant+    main : IO ()+    main = do+      putStr "Look! I figured out how big size_t is! It's "+      putStr (show sizeTSize)+      putStr " bytes!"++Yay! We... asked the user something at compile time? That's not very+good, actually. Our library is going to be difficult to compile! This+is hardly a step up from having them edit in the size of ``size_t``+themselves!++Don't worry, there's a better way.++Foreign Functions+=================++It's actually pretty easy to write a C function that figures out the+size of ``size_t``:++.. code:: c++    int sizeof_size_t() { return sizeof(size_t); }++(Why an int and not a ``size_t``? The FFI needs to know how to receive+the return value of this function and translate it into an Idris+value. If we knew how to do this for values of C type ``size_t``, we+wouldn't need to write this function at all! If we really wanted to be+safe from overflow, we could use an array of multiple integers, but+the SIZE of ``size_t`` is never going to be a 65535 byte integer.)++So now we can get the size of ``size_t`` as long as we're in C code.+We'd like to be able to use this from Idris. Can we do this? It turns+out we can.++``foreign``+-------------++With foreign, we can turn a C function into an IO action. It works+like this:++.. code-block:: idris++    getSizeT : IO Int+    getSizeT = foreign FFI_C "sizeof_size_t" (IO Int)++Pretty simple. ``foreign`` takes a specification of what function it+needs to call and that function's return type.++Running foreign functions+-------------------------++This is all well and good for writing code that will typecheck. To+actually run the code, we'll need to do just a bit more work. Exactly+what we need to do depends on whether we want to interpret or compile+our code.++In the interpreter+------------------++If we want to call our foreign functions from interpreted code (such+as the REPL or a type provider), we need to dynamically link a library+containing the symbols we need. This is pretty easy to do with the+``%dynamic`` directive:++.. code-block:: idris++    %dynamic "./filename.so"++Note that the leading "./" is important: currently, the string you+provide is interpreted as by ``dlopen()``, which on Unix does not search+in the current directory by default. If you use the "./", the library+will be searched for in the directory from which you run idris (*not*+the location of the file you're running!). Of course, if you're using+functions from an installed library rather than something you wrote+yourself, the "./" is not necessary.++In an executable+----------------++If we want to run our code from an executable, we can statically link+instead. We'll use the ``%include`` and ``%link`` directives:++.. code-block:: idris++    %include C "filename.h"+    %link C "filename.o"++Note the extra argument to the directive! We specify that we're+linking a C header and library. Also, unlike ``%dynamic``, these+directives search in the current directory by default. (That is, the+directory from which we run idris.)++Putting it all together+=======================++So, at the beginning of this article I said we'd use type providers to+port ``struct stat`` to Idris. The relevant part is just translating+all the mysterious typedef'd C types into Idris types, and that's what+we'll do here.++First, let's write a C file containing functions that we'll bind to.++.. code-block:: c++    /* stattypes.c */+    #include <sys/stat.h>++    int sizeof_dev_t() { return sizeof(dev_t); }+    int sizeof_ino_t() { return sizeof(ino_t); }+    /* lots more functions like this */++Next, an Idris file to define our providers:++.. code-block:: idris++    -- Providers.idr+    module Providers++    %dynamic "./stattypes.so"++    sizeOfDevT : IO Int+    sizeOfDevT = foreign FFI_C "sizeof_dev_t" (IO Int)+    {- lots of similar functions -}++    -- Indicates how many bits are used to represent various system+    -- stat types.+    data BitWidth = B8 | B16 | B32 | B64++    implementation Show BitWidth where+      show B8 = "8 bits"+      show B16 = "16 bits"+      show B32 = "32 bits"+      show B64 = "64 bits"++    -- Now we have an integer, but we want a Provider BitWidth.+    -- Since our sizeOf* functions are ordinary IO actions, we+    -- can just map over them.+    bytesToType : Int -> Provider BitWidth+    bytesToType 1 = Provide B8  -- "8 bit value"+    bytesToType 2 = Provide B16+    bytesToType 4 = Provide B32+    bytesToType 8 = Provide B64+    bytesToType _ = Error "Unrecognised integral type."++    getDevT : IO (Provider BitWidth)+    getDevT = map bytesToType sizeOfDevT+    {- lots of similar functions -}++Finally, we'll write one more idris file where we use the type+providers:++.. code-block:: idris++    -- Main.idr+    module Main+    import Providers+    %language TypeProviders+    %provide (DevTBitWidth : BitWidth) with getDevT++    -- We can now use DevTBitWidth in our program!+    main : IO ()+    main = putStrLn $ "size of dev_t: " ++ show DevTBitWidth
+ docs/image/effects-tree.png view

binary file changed (absent → 37773 bytes)

+ docs/index.rst view
@@ -0,0 +1,27 @@+.. Idris Manual documentation master file, created by+   sphinx-quickstart on Sat Feb 28 20:41:47 2015.+   You can adapt this file completely to your liking, but it should at least+   contain the root `toctree` directive.++Documentation for the Idris Language+====================================++.. note::++   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/+++.. toctree::+   :maxdepth: 1++   tutorial/index+   faq/faq+   effects/index+   proofs/index+   reference/index+   guides/index
+ docs/listing/idris-prompt-helloworld.txt view
@@ -0,0 +1,15 @@+$ idris hello.idr+     ____    __     _+    /  _/___/ /____(_)____+    / // __  / ___/ / ___/     Version 0.12.3+  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/+ /___/\__,_/_/  /_/____/       Type :? for help++Type checking ./hello.idr+*hello> :t main+Main.main : IO ()+*hello> :c hello+*hello> :q+Bye bye+$ ./hello+Hello world
+ docs/listing/idris-prompt-interp.txt view
@@ -0,0 +1,12 @@+$ idris interp.idr+     ____    __     _+    /  _/___/ /____(_)____+    / // __  / ___/ / ___/     Version 0.12.3+  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/+ /___/\__,_/_/  /_/____/       Type :? for help++Type checking ./interp.idr+*interp> :exec+Enter a number: 6+720+*interp>
+ docs/listing/idris-prompt-start.txt view
@@ -0,0 +1,8 @@+$ idris+    ____    __     _+   /  _/___/ /____(_)____+   / // __  / ___/ / ___/     Version 0.12.3+ _/ // /_/ / /  / (__  )      http://www.idris-lang.org/+/___/\__,_/_/  /_/____/       Type :? for help++Idris>
+ docs/make.bat view
@@ -0,0 +1,263 @@+@ECHO OFF++REM Command file for Sphinx documentation++if "%SPHINXBUILD%" == "" (+	set SPHINXBUILD=sphinx-build+)+set BUILDDIR=_build+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .+set I18NSPHINXOPTS=%SPHINXOPTS% .+if NOT "%PAPER%" == "" (+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%+	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%+)++if "%1" == "" goto help++if "%1" == "help" (+	:help+	echo.Please use `make ^<target^>` where ^<target^> is one of+	echo.  html       to make standalone HTML files+	echo.  dirhtml    to make HTML files named index.html in directories+	echo.  singlehtml to make a single large HTML file+	echo.  pickle     to make pickle files+	echo.  json       to make JSON files+	echo.  htmlhelp   to make HTML files and a HTML help project+	echo.  qthelp     to make HTML files and a qthelp project+	echo.  devhelp    to make HTML files and a Devhelp project+	echo.  epub       to make an epub+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter+	echo.  text       to make text files+	echo.  man        to make manual pages+	echo.  texinfo    to make Texinfo files+	echo.  gettext    to make PO message catalogs+	echo.  changes    to make an overview over all changed/added/deprecated items+	echo.  xml        to make Docutils-native XML files+	echo.  pseudoxml  to make pseudoxml-XML files for display purposes+	echo.  linkcheck  to check all external links for integrity+	echo.  doctest    to run all doctests embedded in the documentation if enabled+	echo.  coverage   to run coverage check of the documentation if enabled+	goto end+)++if "%1" == "clean" (+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i+	del /q /s %BUILDDIR%\*+	goto end+)+++REM Check if sphinx-build is available and fallback to Python version if any+%SPHINXBUILD% 2> nul+if errorlevel 9009 goto sphinx_python+goto sphinx_ok++:sphinx_python++set SPHINXBUILD=python -m sphinx.__init__+%SPHINXBUILD% 2> nul+if errorlevel 9009 (+	echo.+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx+	echo.installed, then set the SPHINXBUILD environment variable to point+	echo.to the full path of the 'sphinx-build' executable. Alternatively you+	echo.may add the Sphinx directory to PATH.+	echo.+	echo.If you don't have Sphinx installed, grab it from+	echo.http://sphinx-doc.org/+	exit /b 1+)++:sphinx_ok+++if "%1" == "html" (+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.+	goto end+)++if "%1" == "dirhtml" (+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.+	goto end+)++if "%1" == "singlehtml" (+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.+	goto end+)++if "%1" == "pickle" (+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished; now you can process the pickle files.+	goto end+)++if "%1" == "json" (+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished; now you can process the JSON files.+	goto end+)++if "%1" == "htmlhelp" (+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished; now you can run HTML Help Workshop with the ^+.hhp project file in %BUILDDIR%/htmlhelp.+	goto end+)++if "%1" == "qthelp" (+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished; now you can run "qcollectiongenerator" with the ^+.qhcp project file in %BUILDDIR%/qthelp, like this:+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\IdrisManual.qhcp+	echo.To view the help file:+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\IdrisManual.ghc+	goto end+)++if "%1" == "devhelp" (+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished.+	goto end+)++if "%1" == "epub" (+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The epub file is in %BUILDDIR%/epub.+	goto end+)++if "%1" == "latex" (+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.+	goto end+)++if "%1" == "latexpdf" (+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex+	cd %BUILDDIR%/latex+	make all-pdf+	cd %~dp0+	echo.+	echo.Build finished; the PDF files are in %BUILDDIR%/latex.+	goto end+)++if "%1" == "latexpdfja" (+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex+	cd %BUILDDIR%/latex+	make all-pdf-ja+	cd %~dp0+	echo.+	echo.Build finished; the PDF files are in %BUILDDIR%/latex.+	goto end+)++if "%1" == "text" (+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The text files are in %BUILDDIR%/text.+	goto end+)++if "%1" == "man" (+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The manual pages are in %BUILDDIR%/man.+	goto end+)++if "%1" == "texinfo" (+	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.+	goto end+)++if "%1" == "gettext" (+	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.+	goto end+)++if "%1" == "changes" (+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes+	if errorlevel 1 exit /b 1+	echo.+	echo.The overview file is in %BUILDDIR%/changes.+	goto end+)++if "%1" == "linkcheck" (+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck+	if errorlevel 1 exit /b 1+	echo.+	echo.Link check complete; look for any errors in the above output ^+or in %BUILDDIR%/linkcheck/output.txt.+	goto end+)++if "%1" == "doctest" (+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest+	if errorlevel 1 exit /b 1+	echo.+	echo.Testing of doctests in the sources finished, look at the ^+results in %BUILDDIR%/doctest/output.txt.+	goto end+)++if "%1" == "coverage" (+	%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage+	if errorlevel 1 exit /b 1+	echo.+	echo.Testing of coverage in the sources finished, look at the ^+results in %BUILDDIR%/coverage/python.txt.+	goto end+)++if "%1" == "xml" (+	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The XML files are in %BUILDDIR%/xml.+	goto end+)++if "%1" == "pseudoxml" (+	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml+	if errorlevel 1 exit /b 1+	echo.+	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.+	goto end+)++:end
+ docs/proofs/index.rst view
@@ -0,0 +1,25 @@+.. _proofs-index:++###############+Theorem Proving+###############++A tutorial on theorem proving in Idris. ++.. note::++   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/++.. toctree::+   :maxdepth: 1++   pluscomm+   inductive+   patterns+   interactive+
+ docs/proofs/inductive.rst view
@@ -0,0 +1,99 @@+****************+Inductive Proofs+****************++Before embarking on proving ``plus_commutes`` in Idris itself, let us+consider the overall structure of a proof of some property of natural+numbers. Recall that they are defined recursively, as follows:++.. code-block:: idris++    data Nat : Type where+         Z : Nat+         S : Nat -> Nat++A *total* function over natural numbers must both terminate, and cover+all possible inputs. Idris checks functions for totality by checking that+all inputs are covered, and that all recursive calls are on+*structurally smaller* values (so recursion will always reach a base+case). Recalling ``plus``:++.. code-block:: idris++    plus : Nat -> Nat -> Nat+    plus Z     m = m+    plus (S k) m = S (plus k m)++This is total because it covers all possible inputs (the first argument+can only be ``Z`` or ``S k`` for some ``k``, and the second argument+``m`` covers all possible ``Nat``) and in the recursive call, ``k``+is structurally smaller than ``S k`` so the first argument will always+reach the base case ``Z`` in any sequence of recursive calls.++In some sense, this resembles a mathematical proof by induction (and+this is no coincidence!). For some property ``P`` of a natural number+``x``, we can show that ``P`` holds for all ``x`` if:++-  ``P`` holds for zero (the base case).++-  Assuming that ``P`` holds for ``k``, we can show ``P`` also holds for+   ``S k`` (the inductive step).++In ``plus``, the property we are trying to show is somewhat trivial (for+all natural numbers ``x``, there is a ``Nat`` which need not have any+relation to ``x``). However, it still takes the form of a base case and+an inductive step. In the base case, we show that there is a ``Nat``+arising from ``plus n m`` when ``n = Z``, and in the inductive step we+show that there is a ``Nat`` arising when ``n = S k`` and we know we can+get a ``Nat`` inductively from ``plus k m``. We could even write a+function capturing all such inductive definitions:++.. code-block:: idris++    nat_induction : (P : Nat -> Type) ->             -- Property to show+                    (P Z) ->                         -- Base case+                    ((k : Nat) -> P k -> P (S k)) -> -- Inductive step+                    (x : Nat) ->                     -- Show for all x+                    P x+    nat_induction P p_Z p_S Z = p_Z+    nat_induction P p_Z p_S (S k) = p_S k (nat_induction P p_Z p_S k)++Using ``nat_induction``, we can implement an equivalent inductive+version of ``plus``:++.. code-block:: idris++    plus_ind : Nat -> Nat -> Nat+    plus_ind n m+       = nat_induction (\x => Nat)+                       m                      -- Base case, plus_ind Z m+                       (\k, k_rec => S k_rec) -- Inductive step plus_ind (S k) m+                                              -- where k_rec = plus_ind k m+                       n++To prove that ``plus n m = plus m n`` for all natural numbers ``n`` and+``m``, we can also use induction. Either we can fix ``m`` and perform+induction on ``n``, or vice versa. We can sketch an outline of a proof;+performing induction on ``n``, we have:++-  Property ``P`` is ``\x => plus x m = plus m x``.++-  Show that ``P`` holds in the base case and inductive step:++   -  | Base case: ``P Z``, i.e.+      | ``plus Z m = plus m Z``, which reduces to+      | ``m = plus m Z`` due to the definition of ``plus``.++   -  | Inductive step: Inductively, we know that ``P k`` holds for a specific, fixed ``k``, i.e.+      | ``plus k m = plus m k`` (the induction hypothesis). Given this, show ``P (S k)``, i.e.+      | ``plus (S k) m = plus m (S k)``, which reduces to+      | ``S (plus k m) = plus m (S k)``. From the induction hypothesis, we can rewrite this to+      | ``S (plus m k) = plus m (S k)``.++To complete the proof we therefore need to show that ``m = plus m Z``+for all natural numbers ``m``, and that ``S (plus m k) = plus m (S k)``+for all natural numbers ``m`` and ``k``. Each of these can also be+proved by induction, this time on ``m``.++We are now ready to embark on a proof of commutativity of ``plus``+formally in Idris.
+ docs/proofs/interactive.rst view
@@ -0,0 +1,169 @@+***************************************+DEPRECATED: Interactive Theorem Proving+***************************************++.. warning::+   The interactive theorem-proving interface documented here has been+   deprecated in favor of :ref:`elaborator-reflection`.++Idris also supports interactive theorem proving via tactics. This+is generally not recommended to be used directly, but rather used as a+mechanism for building proof automation which is beyond the scope of this+tutorial. In this section, we briefly discus tactics.++One way to write proofs interactively is to write the general *structure* of+the proof, and use the interactive mode to complete the details.+Consider the following definition, proved in :ref:`sect-theorems`:++.. code-block:: idris++    plusReduces : (n:Nat) -> plus Z n = n++We’ll be constructing the proof by *induction*, so we write the cases for ``Z``+and ``S``, with a recursive call in the ``S`` case giving the inductive+hypothesis, and insert *holes* for the rest of the definition:++.. code-block:: idris++    plusReducesZ' : (n:Nat) -> n = plus n Z+    plusReducesZ' Z     = ?plusredZ_Z+    plusReducesZ' (S k) = let ih = plusReducesZ' k in+                          ?plusredZ_S++On running , two global names are created, ``plusredZ_Z`` and+``plusredZ_S``, with no definition. We can use the ``:m`` command at the+prompt to find out which holes are still to be solved (or, more+precisely, which functions exist but have no definitions), then the+``:t`` command to see their types:++.. code-block:: idris++    *theorems> :m+    Global holes:+            [plusredZ_S,plusredZ_Z]++.. code-block:: idris++    *theorems> :t plusredZ_Z+    plusredZ_Z : Z = plus Z Z++    *theorems> :t plusredZ_S+    plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z++The ``:p`` command enters interactive proof mode, which can be used to+complete the missing definitions.++.. code-block:: idris++    *theorems> :p plusredZ_Z++    ---------------------------------- (plusredZ_Z) --------+    {hole0} : Z = plus Z Z++This gives us a list of premises (above the line; there are none here)+and the current goal (below the line; named ``{hole0}`` here). At the+prompt we can enter tactics to direct the construction of the proof. In+this case, we can normalise the goal with the ``compute`` tactic:++.. code-block:: idris++    -plusredZ_Z> compute++    ---------------------------------- (plusredZ_Z) --------+    {hole0} : Z = Z++Now we have to prove that ``Z`` equals ``Z``, which is easy to prove by+``Refl``. To apply a function, such as ``Refl``, we use ``refine`` which+introduces subgoals for each of the function’s explicit arguments+(``Refl`` has none):++.. code-block:: idris++    -plusredZ_Z> refine Refl+    plusredZ_Z: no more goals++Here, we could also have used the ``trivial`` tactic, which tries to+refine by ``Refl``, and if that fails, tries to refine by each name in+the local context. When a proof is complete, we use the ``qed`` tactic+to add the proof to the global context, and remove the hole from the+unsolved holes list. This also outputs a trace of the proof:++.. code-block:: idris++    -plusredZ_Z> qed+    plusredZ_Z = proof+        compute+        refine Refl++.. code-block:: idris++    *theorems> :m+    Global holes:+            [plusredZ_S]++The ``:addproof`` command, at the interactive prompt, will add the proof+to the source file (effectively in an appendix). Let us now prove the+other required lemma, ``plusredZ_S``:++.. code-block:: idris++    *theorems> :p plusredZ_S++    ---------------------------------- (plusredZ_S) --------+    {hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z++In this case, the goal is a function type, using ``k`` (the argument+accessible by pattern matching) and ``ih`` — the local variable+containing the result of the recursive call. We can introduce these as+premises using the ``intro`` tactic twice (or ``intros``, which+introduces all arguments as premises). This gives:++.. code-block:: idris++      k : Nat+      ih : k = plus k Z+    ---------------------------------- (plusredZ_S) --------+    {hole2} : S k = plus (S k) Z++Since plus is defined by recursion on its first argument, the term+``plus (S k) Z`` in the goal can be simplified, so we use ``compute``.++.. code-block:: idris++      k : Nat+      ih : k = plus k Z+    ---------------------------------- (plusredZ_S) --------+    {hole2} : S k = S (plus k Z)++We know, from the type of ``ih``, that ``k = plus k Z``, so we would+like to use this knowledge to replace ``plus k Z`` in the goal with+``k``. We can achieve this with the ``rewrite`` tactic:++.. code-block:: idris++    -plusredZ_S> rewrite ih++      k : Nat+      ih : k = plus k Z+    ---------------------------------- (plusredZ_S) --------+    {hole3} : S k = S k++    -plusredZ_S>++The ``rewrite`` tactic takes an equality proof as an argument, and tries+to rewrite the goal using that proof. Here, it results in an equality+which is trivially provable:++.. code-block:: idris++    -plusredZ_S> trivial+    plusredZ_S: no more goals+    -plusredZ_S> qed+    plusredZ_S = proof {+        intros;+        rewrite ih;+        trivial;+    }++Again, we can add this proof to the end of our source file using the+``:addproof`` command at the interactive prompt.
+ docs/proofs/patterns.rst view
@@ -0,0 +1,351 @@+***********************+Pattern Matching Proofs+***********************++In this section, we will provide a proof of ``plus_commutes`` directly,+by writing a pattern matching definition. We will use interactive+editing features extensively, since it is significantly easier to+produce a proof when the machine can give the types of intermediate+values and construct components of the proof itself. The commands we+will use are summarised below. Where we refer to commands+directly, we will use the Vim version, but these commands have a direct+mapping to Emacs commands.+++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++|Command              | Vim binding     | Emacs binding | Explanation                                                                                |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++| Check type          | ``\t``          | ``C-c C-t``   | Show type of identifier or hole under the cursor.                                          |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++| Proof search        | ``\o``          | ``C-c C-a``   | Attempt to solve hole under the cursor by applying simple proof search.                    |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++| Make new definition | ``\d``          | ``C-c C-s``   | Add a template definition for the type defined under the cursor.                           |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++| Make lemma          | ``\l``          | ``C-c C-e``   | Add a top level function with a type which solves the hole under the cursor.               |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++| Split cases         | ``\c``          | ``C-c C-c``   | Create new constructor patterns for each possible case of the variable under the cursor.   |++---------------------+-----------------+---------------+--------------------------------------------------------------------------------------------++++Creating a Definition+=====================++To begin, create a file ``pluscomm.idr`` containing the following type+declaration:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n++To create a template definition for the proof, press ``\d`` (or the+equivalent in your editor of choice) on the line with the type+declaration. You should see:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes n m = ?plus_commutes_rhs++To prove this by induction on ``n``, as we sketched in Section+:ref:`sect-inductive`, we begin with a case split on ``n`` (press+``\c`` with the cursor over the ``n`` in the definition.) You+should see:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes Z m = ?plus_commutes_rhs_1+    plus_commutes (S k) m = ?plus_commutes_rhs_2++If we inspect the types of the newly created holes,+``plus_commutes_rhs_1`` and ``plus_commutes_rhs_2``, we see that the+type of each reflects that ``n`` has been refined to ``Z`` and ``S k``+in each respective case. Pressing ``\t`` over+``plus_commutes_rhs_1`` shows:++.. code-block:: idris++      m : Nat+    --------------------------------------+    plus_commutes_rhs_1 : m = plus m 0++Note that ``Z`` renders as ``0`` because the pretty printer renders+natural numbers as integer literals for readability. Similarly, for+``plus_commutes_rhs_2``:++.. code-block:: idris++      k : Nat+      m : Nat+    --------------------------------------+    plus_commutes_rhs_2 : S (plus k m) = plus m (S k)++It is a good idea to give these slightly more meaningful names:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes Z m = ?plus_commutes_Z+    plus_commutes (S k) m = ?plus_commutes_S++Base Case+=========++We can create a separate lemma for the base case interactively, by+pressing ``\l`` with the cursor over ``plus_commutes_Z``. This+yields:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes Z m = plus_commutes_Z+    plus_commutes (S k) m = ?plus_commutes_S++That is, the hole has been filled with a call to a top level+function ``plus_commutes_Z``. The argument ``m`` has been made implicit+because it can be inferred from context when it is applied.++Unfortunately, we cannot prove this lemma directly, since ``plus`` is+defined by matching on its *first* argument, and here ``plus m 0`` has a+specific value for its *second argument* (in fact, the left hand side of+the equality has been reduced from ``plus 0 m``.) Again, we can prove+this by induction, this time on ``m``.++First, create a template definition with ``\d``:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z = ?plus_commutes_Z_rhs++Since we are going to write this by induction on ``m``, which is+implicit, we will need to bring ``m`` into scope manually:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z {m} = ?plus_commutes_Z_rhs++Now, case split on ``m`` with ``\c``:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z {m = Z} = ?plus_commutes_Z_rhs_1+    plus_commutes_Z {m = (S k)} = ?plus_commutes_Z_rhs_2++Checking the type of ``plus_commutes_Z_rhs_1`` shows the following,+which is easily proved by reflection:++.. code-block:: idris++    --------------------------------------+    plus_commutes_Z_rhs_1 : 0 = 0++For such trivial proofs, we can let write the proof automatically by+pressing ``\o`` with the cursor over ``plus_commutes_Z_rhs_1``.+This yields:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z {m = Z} = Refl+    plus_commutes_Z {m = (S k)} = ?plus_commutes_Z_rhs_2++For ``plus_commutes_Z_rhs_2``, we are not so lucky:++.. code-block:: idris++      k : Nat+    --------------------------------------+    plus_commutes_Z_rhs_2 : S k = S (plus k 0)++Inductively, we should know that ``k = plus k 0``, and we can get access+to this inductive hypothesis by making a recursive call on k, as+follows:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z {m = Z} = Refl+    plus_commutes_Z {m = (S k)} = let rec = plus_commutes_Z {m=k} in+                                      ?plus_commutes_Z_rhs_2++For ``plus_commutes_Z_rhs_2``, we now see:++.. code-block:: idris++      k : Nat+      rec : k = plus k (fromInteger 0)+    --------------------------------------+    plus_commutes_Z_rhs_2 : S k = S (plus k 0)++Again, the ``fromInteger 0`` is merely due to ``Nat`` having an implementation+of the ``Num`` interface. So we know that ``k = plus k 0``, but how do+we use this to update the goal to ``S k = S k``?++To achieve this, Idris provides a ``replace`` function as part of the+prelude:++.. code-block:: idris++    *pluscomm> :t replace+    replace : (x = y) -> P x -> P y++Given a proof that ``x = y``, and a property ``P`` which holds for+``x``, we can get a proof of the same property for ``y``, because we+know ``x`` and ``y`` must be the same. In practice, this function can be+a little tricky to use because in general the implicit argument ``P``+can be hard to infer by unification, so Idris provides a high level+syntax which calculates the property and applies ``replace``:++.. code-block:: idris++    rewrite prf in expr++If we have ``prf : x = y``, and the required type for ``expr`` is some+property of ``x``, the ``rewrite ... in`` syntax will search for ``x``+in the required type of ``expr`` and replace it with ``y``. Concretely,+in our example, we can say:++.. code-block:: idris++    plus_commutes_Z {m = (S k)} = let rec = plus_commutes_Z {m=k} in+                                      rewrite rec in ?plus_commutes_Z_rhs_2++Checking the type of ``plus_commutes_Z_rhs_2`` now gives:++.. code-block:: idris++      k : Nat+      rec : k = plus k (fromInteger 0)+      _rewrite_rule : plus k 0 = k+    --------------------------------------+    plus_commutes_Z_rhs_2 : S (plus k 0) = S (plus k 0)++Using the rewrite rule ``rec`` (which we can see in the context here as+``_rewrite_rule``\  [1]_, the goal type has been updated with ``k``+replaced by ``plus k 0``.++Alternatively, we could have applied the rewrite in the other direction+using the ``sym`` function:++.. code-block:: idris++    *pluscomm> :t sym+    sym : (l = r) -> r = l++.. code-block:: idris++    plus_commutes_Z {m = (S k)} = let rec = plus_commutes_Z {m=k} in+                                      rewrite sym rec in ?plus_commutes_Z_rhs_2++In this case, inspecting the type of the hole gives:++.. code-block:: idris++      k : Nat+      rec : k = plus k (fromInteger 0)+      _rewrite_rule : k = plus k 0+    --------------------------------------+    plus_commutes_Z_rhs_2 : S k = S k++Either way, we can use proof search (``\o``) to complete the+proof, giving:++.. code-block:: idris++    plus_commutes_Z : m = plus m 0+    plus_commutes_Z {m = Z} = Refl+    plus_commutes_Z {m = (S k)} = let rec = plus_commutes_Z {m=k} in+                                      rewrite rec in Refl++The base case is now complete.++Inductive Step+==============++Our main theorem, ``plus_commutes`` should currently be in the following+state:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes Z m = plus_commutes_Z+    plus_commutes (S k) m = ?plus_commutes_S++Looking again at the type of ``plus_commutes_S``, we have:++.. code-block:: idris++      k : Nat+      m : Nat+    --------------------------------------+    plus_commutes_S : S (plus k m) = plus m (S k)++Conveniently, by induction we can immediately tell that+``plus k m = plus m k``, so let us rewrite directly by making a+recursive call to ``plus_commutes``. We add this directly, by hand, as+follows:++.. code-block:: idris++    plus_commutes : (n : Nat) -> (m : Nat) -> n + m = m + n+    plus_commutes Z m = plus_commutes_Z+    plus_commutes (S k) m = rewrite plus_commutes k m in ?plus_commutes_S++Checking the type of ``plus_commutes_S`` now gives:++.. code-block:: idris++      k : Nat+      m : Nat+      _rewrite_rule : plus m k = plus k m+    --------------------------------------+    plus_commutes_S : S (plus m k) = plus m (S k)++The good news is that ``m`` and ``k`` now appear in the correct order.+However, we still have to show that the successor symbol ``S`` can be+moved to the front in the right hand side of this equality. This+remaining lemma takes a similar form to the ``plus_commutes_Z``; we+begin by making a new top level lemma with ``\l``. This gives:++.. code-block:: idris++    plus_commutes_S : (k : Nat) -> (m : Nat) -> S (plus m k) = plus m (S k)++Unlike the previous case, ``k`` and ``m`` are not made implicit because+we cannot in general infer arguments to a function from its result.+Again, we make a template definition with ``\d``:++.. code-block:: idris++    plus_commutes_S : (k : Nat) -> (m : Nat) -> S (plus m k) = plus m (S k)+    plus_commutes_S k m = ?plus_commutes_S_rhs++Again, this is defined by induction over ``m``, since ``plus`` is+defined by matching on its first argument. The complete definition is:++.. code-block:: idris++    total+    plus_commutes_S : (k : Nat) -> (m : Nat) -> S (plus m k) = plus m (S k)+    plus_commutes_S k Z = Refl+    plus_commutes_S k (S j) = rewrite plus_commutes_S k j in Refl++All holes have now been solved.++The ``total`` annotation means that we require the final function to+pass the totality checker; i.e. it will terminate on all possible+well-typed inputs. This is important for proofs, since it provides a+guarantee that the proof is valid in *all* cases, not just those for+which it happens to be well-defined.++Now that ``plus_commutes`` has a ``total`` annotation, we have completed the+proof of commutativity of addition on natural numbers.++.. [1]+   Note that the left and right hand sides of the equality have been+   swapped, because ``replace`` takes a proof of ``x=y`` and the+   property for ``x``, not ``y``.
+ docs/proofs/pluscomm.rst view
@@ -0,0 +1,189 @@+********************************************+Running example: Addition of Natural Numbers+********************************************++Throughout this tutorial, we will be working with the following+function, defined in the Idris prelude, which defines addition on+natural numbers:++.. code-block:: idris++    plus : Nat -> Nat -> Nat+    plus Z     m = m+    plus (S k) m = S (plus k m)++It is defined by the above equations, meaning that we have for free the+properties that adding ``m`` to zero always results in ``m``, and that+adding ``m`` to any non-zero number ``S k`` always results in+``S (plus k m)``. We can see this by evaluation at the Idris REPL (i.e.+the prompt, the read-eval-print loop):++.. code-block:: idris++    Idris> \m => plus Z m+    \m => m : Nat -> Nat++    Idris> \k,m => plus (S k) m+    \k => \m => S (plus k m) : Nat -> Nat -> Nat++Note that unlike many other language REPLs, the Idris REPL performs+evaluation on *open* terms, meaning that it can reduce terms which+appear inside lambda bindings, like those above. Therefore, we can+introduce unknowns ``k`` and ``m`` as lambda bindings and see how+``plus`` reduces.++The ``plus`` function has a number of other useful properties, for+example:++-  It is *commutative*, that is for all ``Nat`` inputs ``n`` and ``m``,+   we know that ``plus n m = plus m n``.++-  It is *associative*, that is for all ``Nat`` inputs ``n``, ``m`` and+   ``p``, we know that ``plus n (plus m p) = plus (plus m n) p``.++We can use these properties in an Idris program, but in order to do so+we must *prove* them.++Equality Proofs+===============++Idris has a built-in propositional equality type, conceptually defined+as follows:++.. code-block:: idris++    data (=) : a -> b -> Type where+       Refl : x = x++Note that this must be built-in, rather than defined in the library,+because ``=`` is a reserved operator — you cannot define this directly+in your own code.++It is *propositional* equality, where the type states that any two+values in different types ``a`` and ``b`` may be proposed to be equal.+There is only one way to *prove* equality, however, which is by+reflexivity (``Refl``).++We have a *type* for propositional equality here, and correspondingly a+*program* inhabiting an instance of this type can be seen as a proof of+the corresponding proposition [1]_. So, trivially, we can prove that+``4`` equals ``4``:++.. code-block:: idris++    four_eq : 4 = 4+    four_eq = Refl++However, trying to prove that ``4 = 5`` results in failure:++.. code-block:: idris++    four_eq_five : 4 = 5+    four_eq_five = Refl++The type ``4 = 5`` is a perfectly valid type, but is uninhabited, so+when trying to type check this definition, Idris gives the following+error:++::++    When elaborating right hand side of four_eq_five:+    Type mismatch between+            x = x (Type of Refl)+    and+            4 = 5 (Expected type)++Type checking equality proofs+-----------------------------++An important step in type checking Idris programs is *unification*,+which attempts to resolve implicit arguments such as the implicit+argument ``x`` in ``Refl``. As far as our understanding of type checking+proofs is concerned, it suffices to know that unifying two terms+involves reducing both to normal form then trying to find an assignment+to implicit arguments which will make those normal forms equal.++When type checking ``Refl``, Idris requires that the type is of the form+``x = x``, as we see from the type of ``Refl``. In the case of+``four_eq_five``, Idris will try to unify the expected type ``4 = 5``+with the type of ``Refl``, ``x = x``, notice that a solution requires+that ``x`` be both ``4`` and ``5``, and therefore fail.++Since type checking involves reduction to normal form, we can write the+following equalities directly:++.. code-block:: idris++    twoplustwo_eq_four : 2 + 2 = 4+    twoplustwo_eq_four = Refl++    plus_reduces_Z : (m : Nat) -> plus Z m = m+    plus_reduces_Z m = Refl++    plus_reduces_Sk : (k, m : Nat) -> plus (S k) m = S (plus k m)+    plus_reduces_Sk k m = Refl++Heterogeneous Equality+======================++Equality in Idris is *heterogeneous*, meaning that we can even propose+equalities between values in different types:++.. code-block:: idris++    idris_not_php : 2 = "2"++Obviously, in Idris the type ``2 = "2"`` is uninhabited, and one might+wonder why it is useful to be able to propose equalities between values+in different types. However, with dependent types, such equalities can+arise naturally. For example, if two vectors are equal, their lengths+must be equal:++.. code-block:: idris++    vect_eq_length : (xs : Vect n a) -> (ys : Vect m a) ->+                     (xs = ys) -> n = m++In the above declaration, ``xs`` and ``ys`` have different types because+their lengths are different, but we would still like to draw a+conclusion about the lengths if they happen to be equal. We can define+``vect_eq_length`` as follows:++.. code-block:: idris++    vect_eq_length xs xs Refl = Refl++By matching on ``Refl`` for the third argument, we know that the only+valid value for ``ys`` is ``xs``, because they must be equal, and+therefore their types must be equal, so the lengths must be equal.++Alternatively, we can put an underscore for the second ``xs``, since+there is only one value which will type check:++.. code-block:: idris++    vect_eq_length xs _ Refl = Refl++Properties of ``plus``+======================++Using the ``(=)`` type, we can now state the properties of ``plus``+given above as Idris type declarations:++.. code-block:: idris++    plus_commutes : (n, m : Nat) -> plus n m = plus m n+    plus_assoc : (n, m, p : Nat) -> plus n (plus m p) = plus (plus n m) p++Both of these properties (and many others) are proved for natural number+addition in the Idris standard library, using ``(+)`` from the ``Num``+interface rather than using ``plus`` directly. They have the names+``plusCommutative`` and ``plusAssociative`` respectively.++In the remainder of this tutorial, we will explore several different+ways of proving ``plus_commutes`` (or, to put it another way, writing+the function.) We will also discuss how to use such equality proofs, and+see where the need for them arises in practice.++.. [1]+   This is known as the Curry-Howard correspondence.
+ docs/reference/codegen.rst view
@@ -0,0 +1,133 @@+************************+Code Generation Targets+************************++``Idris`` has been designed such that the compiler can generate code for+different backends upon request. By default ``Idris`` generates a ``C``+backend when generating an executable. Included within the standard Idris installation are backends for Javascript and Node.js.++However, there are third-party code generators out there.  Below we+describe some of these backends and how you can use them when+compiling your ``Idris`` code. If you want to write your own codegen for your language there is a `stub project on GitHub <https://github.com/idris-lang/idris-emptycg>`__ that can help point you in the right direction.++Official Backends+==================++C Language+----------++Javascript+----------++To generate code that is tailored for running in the browser+issue the following command:++::++    $ idris --codegen javascript hello.idr -o hello.js+++Generating code for NodeJS is slightly different. Idris outputs a+JavaScript file that can be directly executed via node.++::++    $ idris --codegen node hello.idr -o hello+    $ ./hello+    Hello world+++Idris can produce very big chunks of JavaScript code (hello world+weighs in at 1500 lines). However, the generated code can be minified+using the `closure-compiler+<https://developers.google.com/closure/compiler/>`__ from Google.++::++   java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js hello.js+++Node.js+-------+++Third Party+============++.. note::++   These are third-party code generations and may have bit-rotted or+   do not work with current versions of Idris. Please speak to the+   project's maintainors if there are any problems.+++CIL (.NET, Mono, Unity)+-----------------------++::++    idris --codegen cil Main.idr -o HelloWorld.exe \+      && mono HelloWorld.exe++The resulting assemblies can also be used with .NET or Unity.++Requires `idris-cil <https://github.com/bamboo/idris-cil>`__.++Erlang+------++`Available online <https://github.com/lenary/idris-erlang>`__++Java+----++`Available online <https://github.com/idris-hackers/idris-java>`__+++::++   idris hello.idr --codegen java -o hello.jar+++Note: The resulting .jar is automatically prefixed by a header including+an .sh script to allow executing it directly.++JVM+---++`Available online <https://github.com/mmhelloworld/idris-jvm>`__++LLVM+-----++`Available online <https://github.com/idris-hackers/idris-llvm>`__++Malfunction+------------++`Available online <https://github.com/stedolan/idris-malfunction>`__++Ocaml+-----++`Available online <https://github.com/ziman/idris-ocaml>`__++PHP+---++`Available online <https://github.com/edwinb/idris-php>`__++Python+------++`Available online <https://github.com/ziman/idris-py>`__++Ruby+----++`Available online <https://github.com/mrb/idris-ruby>`__++WS+---++`Available online <https://github.com/edwinb/WS-idr>`__
+ docs/reference/compilation.rst view
@@ -0,0 +1,107 @@+***********************+Compilation and Logging+***********************++This section provides information about the Idris compilation process, and+provides details over how you can follow the process through logging.++Compilation Process+===================++Idris follows the following compilation process:++#. Parsing+#. Type Checking++   #. Elaboration+   #. Coverage+   #. Unification+   #. Totality Checking+   #. Erasure++#. Code Generation++   #. Defunctionalisation+   #. Inlining+   #. Resolving variables+   #. Code Generation+++Type Checking Only+==================++With Idris you can ask it to terminate the compilation process after type checking has completed. This is achieved through use of either:+++ The command line options++  + ``--check`` for files+  + ``--checkpkg`` for packages+++ The REPL command: ``:check``++Use of this option will still result in the generation of the Idris binary ``.ibc`` files, and is suitable if you do not wish to generate code from one of the supported backends.++Logging Output+==============++The internal operation of Idris is captured using a category based logger.+Currently, the logging infrastructure has support for the following categories:+++ Parser++ Elaborator++ Code generation++ Erasure++ Coverage Checking++ IBC generation+++These categories are specified using the command-line option:+``--logging-categories CATS``, where ``CATS`` is a quoted colon+seperated string of the categories you want to see. By default if this+option is not specified all categories are allowed.  Sub-categories+have yet to be defined but will be in the future, especially for the+elaborator.++Further, the verbosity of logging can be controlled by specifying a+logging level between: 1 to 10 using the command-line option: ``--log+<level>``.+++ Level 0: Show no logging output. Default level++ Level 1: High level details of the compilation process.++ Level 2: Provides details of the coverage checking, and further details the elaboration process specifically: Interface, Clauses, Data, Term, and Types,++ Level 3: Provides details of compilation of the IRTS, erasure, parsing, case splitting, and further details elaboration of: Implementations, Providers, and Values.++ Level 4: Provides further details on: Erasure, Coverage Checking, Case splitting, and elaboration of clauses.++ Level 5: Provides details on the prover, and further details elaboration (adding declarations) and compilation of the IRTS.++ Level 6: Further details elaboration and coverage checking.++ Level 7:++ Level 8:++ Level 9:++ Level 10: Further details elaboration.++Environment Variables+=====================++Several paths set by default within the Idris compiler can be+overridden through environment variables.  The provided variables are:++* `IDRIS_CC` Change the `C` compiler used by the `C` backend.+* `IDRIS_CFLAGS` Change the `C` flags passed to the `C` compiler.+* `TARGET`   Change the target directory to generate files.+* `IDRIS_LIBRARY_PATH` Change the location of where installed packages are found.++Alternativly, and perhaps a cleaner approach is to configure these+options using the CLI options.  Idris also supports options to augment+the paths used, and pass options to the code generator backend.++The option `--cg-opt <ARG>` can be used to pass options to the code+generator. The format of `<ARG>` is dependent on the selected backend.++Further, Idris does support multiple include paths.  The CLI option+`-i <dir>` allows you to add a directory to the library search path; this+option can be used multiple times. This is a cleaner option when you+wish to add single directories to the `IDRIS_LIBRARY_PATH` than+ammending `IDRIS_LIBRARY_PATH` directly.+To add directories to the source search path, use the `--sourcepath <dir>` option.++Moreover, rather than using `TARGET` the CLI option `--ibcsubdir` can+be used to direct where built IBC files are placed.
+ docs/reference/documenting.rst view
@@ -0,0 +1,135 @@+.. _sect-documenting:++**********************+Documenting Idris Code+**********************++Idris documentation comes in two major forms: comments, which exist+for a reader’s edification and are ignored by the compiler, and inline+API documentation, which the compiler parses and stores for future+reference. To consult the documentation for a declaration ``f``, write+``:doc f`` at the REPL or use the appropriate command in your editor+(``C-c C-d`` in Emacs, ``<LocalLeader>h`` in Vim).++Comments+========++Use comments to explain why code is written the way that it+is. Idris’s comment syntax is the same as that of Haskell: lines+beginning with ``--`` are comments, and regions bracketed by ``{-``+and ``-}`` are comments even if they extend across multiple+lines. These can be used to comment out lines of code or provide+simple documentation for the readers of Idris code.++Inline Documentation+====================++Idris also supports a comprehensive and rich inline syntax for Idris+code to be generated. This syntax also allows for named parameters and+variables within type signatures to be individually annotated using a+syntax similar to Javadoc parameter annotations.++Documentation always comes before the declaration being documented.+Inline documentation applies to either top-level declarations or to+constructors. Documentation for specific arguments to constructors, type+constructors, or functions can be associated with these arguments using+their names.++The inline documentation for a declaration is an unbroken string of+lines, each of which begins with ``|||`` (three pipe symbols). The+first paragraph of the documentation is taken to be an overview, and+in some contexts, only this overview will be shown. After the+documentation for the declaration as a whole, it is possible to+associate documentation with specific named parameters, which can+either be explicitly name or the results of converting free variables+to implicit parameters.  Annotations are the same as with Javadoc+annotations, that is for the named parameter ``(n : T)``, the+corresponding annotation is ``||| @ n Some description`` that is+placed before the declaration.++Documentation is written in Markdown, though not all contexts will+display all possible formatting (for example, images are not displayed+when viewing documentation in the REPL, and only some terminals render+italics correctly). A comprehensive set of examples is given below.++.. code-block:: idris+++    ||| Modules can also be documented.+    module Docs++    ||| Add some numbers.+    |||+    ||| Addition is really great. This paragraph is not part of the overview.+    ||| Still the same paragraph. Lists are also nifty:+    ||| * Really nifty!+    ||| * Yep!+    ||| * The name `add` is a **bold** choice+    ||| @ n is the recursive param+    ||| @ m is not+    add : (n, m : Nat) -> Nat+    add Z     m = m+    add (S n) m = S (add n m)+++    ||| Append some vectors+    ||| @ a the contents of the vectors+    ||| @ xs the first vector (recursive param)+    ||| @ ys the second vector (not analysed)+    appendV : (xs : Vect n a) -> (ys : Vect m a) -> Vect (add n m) a+    appendV []      ys = ys+    appendV (x::xs) ys = x :: appendV xs ys++    ||| Here's a simple datatype+    data Ty =+      ||| Unit+      UNIT |+      ||| Functions+      ARR Ty Ty++    ||| Points to a place in a typing context+    data Elem : Vect n Ty -> Ty -> Type where+      Here : {ts : Vect n Ty} -> Elem (t::ts) t+      There : {ts : Vect n Ty} -> Elem ts t -> Elem (t'::ts) t++    ||| A more interesting datatype+    ||| @ n the number of free variables+    ||| @ ctxt a typing context for the free variables+    ||| @ ty the type of the term+    data Term : (ctxt : Vect n Ty) -> (ty : Ty) -> Type where++      ||| The constructor of the unit type+      ||| More comment+      ||| @ ctxt the typing context+      UnitCon : {ctxt : Vect n Ty} -> Term ctxt UNIT++      ||| Function application+      ||| @ f the function to apply+      ||| @ x the argument+      App : {ctxt : Vect n Ty} -> (f : Term ctxt (ARR t1 t2)) -> (x : Term ctxt t1) -> Term ctxt t2++      ||| Lambda+      ||| @ body the function body+      Lam : {ctxt : Vect n Ty} -> (body : Term (t1::ctxt) t2) -> Term ctxt (ARR t1 t2)++      ||| Variables+      ||| @ i de Bruijn index+      Var : {ctxt : Vect n Ty} -> (i : Elem ctxt t) -> Term ctxt t++    ||| A computation that may someday finish+    codata Partial : Type -> Type where++      ||| A finished computation+      ||| @ value the result+      Now : (value : a) -> Partial a++      ||| A not-yet-finished computation+      ||| @ rest the remaining work+      Later : (rest : Partial a) -> Partial a++    ||| We can document records, including their fields and constructors+    record Yummy where+      ||| Make a yummy+      constructor MkYummy+      ||| What to eat+      food : String
+ docs/reference/elaborator-reflection.rst view
@@ -0,0 +1,197 @@+.. _elaborator-reflection:++*********************+Elaborator Reflection+*********************++The Idris elaborator is responsible for converting high-level Idris code into the core language.+It is implemented as a kind of embedded tactic language in Haskell, where tactic scripts are written in an *elaboration monad* that provides error handling and a proof state.+For details, see Edwin Brady's 2013 paper in the Journal of Functional Programming.++Elaborator reflection makes the elaboration type as well as a selection of its tactics available to Idris code.+This means that metaprograms written in Idris can have complete control over the elaboration process, generating arbitrary code, and they have access to all of the facilities available in the elaborator, such as higher-order unification, type checking, and emitting auxiliary definitions.++The Elaborator State+====================++The elaborator state contains information about the ongoing elaboration process.+In particular, it contains a *goal type*, which is to be filled by an under-construction *proof term*.+The proof term can contain *holes*, each of which has a scope in which it is valid and a type.+Some holes may additionally contain *guesses*, which can be substituted in the scope of the hole.+The holes are tracked in a *hole queue*, and one of them is *focused*.+In addition to the goal type, proof term, and holes, the elaborator state contains a collection of unsolved unification problems that can affect elaboration.++The elaborator state is not directly available to Idris programs.+Instead, it is modified through the use of *tactics*, which are operations that affect the elaborator state.+A tactic that returns a value of type ``a``, potentially modifying the elaborator state, has type ``Elab a``.+The default tactics are all in the namespace ``Language.Reflection.Elab.Tactics``.+++Running Elaborator Scripts+==========================++On their own, tactics have no effect.+The meta-operation ``%runElab script`` runs ``script`` in the current elaboration context.+For example, the following script constructs the identity function at type ``Nat``:++.. code-block:: idris++    idNat : Nat -> Nat+    idNat = %runElab (do intro `{{x}}+                         fill (Var `{{x}})+                         solve)+++On the right-hand side, the Idris elaborator has the goal ``Nat -> Nat``.+When it encounters the ``%runElab`` directive, it fulfills this goal by running the provided script.+The first tactic, ``intro``, constructs a lambda that binds the name ``x``.+The name argument is optional because a default name can be taken from the function type.+Now, the proof term is of the form ``\x : Nat => {hole}``.+The second tactic, ``fill``, fills this hole with a guess, giving the term ``\x : Nat => {hole≈x}``.+Finally, the ``solve`` tactic instantiates the guess, giving the result ``\x : Nat => x``.++Because elaborator scripts are ordinary Idris expressions, it is also possible to use them in multiple contexts.+Note that there is nothing ``Nat``-specific about the above script.+We can generate identity functions at any concrete type using the same script:++.. code-block:: idris++    mkId : Elab ()+    mkId = do intro `{{x}}+              fill (Var `{{x}})+              solve++    idNat : Nat -> Nat+    idNat = %runElab mkId++    idUnit : () -> ()+    idUnit = %runElab mkId++    idString : String -> String+    idString = %runElab mkId+++Interactively Building Elab Scripts+===================================++You can build an ``Elab`` script interactively at the REPL.+Use the command ``:metavars``, or ``:m`` for short, to list the available holes.+Then, issue the ``:elab <hole>`` command at the REPL+to enter the elaboration shell.++At the shell, you can enter proof tactics to alter the proof state.+You can view the system-provided tactics prior to entering the shell+by issuing the REPL command ``:browse Language.Reflection.Elab.Tactics``.+When you have discharged all goals, you can complete the proof+using the ``:qed`` command and receive in return an elaboration script+that fills the hole.++The interactive elaboration shell accepts a limited number of commands,+including a subset of the commands understood by the normal Idris REPL+as well as some elaboration-specific commands.++General-purpose commands:++- ``:eval <EXPR>``, or ``:e <EXPR>`` for short, evaluates the provided expression+  and prints the result.++- ``:type <EXPR>``, or ``:t <EXPR>`` for short, prints the provided expression+  together with its type.++- ``:search <TYPE>`` searches for definitions having the provided type.++- ``:doc <NAME>`` searches for definitions with the provided name and prints their+  documentation.+++Commands for viewing the proof state:++- ``:state`` displays the current state of the term being constructed. It lists both+  other goals and the current goal.++- ``:term`` displays the current proof term as well as its yet-to-be-filled holes.+++Commands for manipulating the proof state:++- ``:undo`` undoes the effects of the last tactic.++- ``:abandon`` gives up on proving the current lemma and quits the elaboration shell.++- ``:qed`` finishes the script and exits the elaboration shell. The shell will only accept+  this command once it reports, "No more goals." On exit, it will print out the finished+  elaboration script for you to copy into your program.+++Failure+=======++Some tactics may *fail*.+For example, ``intro`` will fail if the focused hole does not have a function type, ``solve`` will fail if the current hole does not contain a guess, and ``fill`` will fail if the term to be filled in has the wrong type.+Scripts can also fail explicitly using the ``fail`` tactic.++To account for failure, there is an ``Alternative`` implementation for ``Elab``.+The ``<|>`` operator first tries the script to its left.+If that script fails, any changes that it made to the state are undone and the right argument is executed.+If the first argument succeeds, then the second argument is not executed.++Querying the Elaboration State+==============================++``Elab`` includes operations to query the elaboration state, allowing scripts to use information about their environment to steer the elaboration process.+The ordinary Idris bind syntax can be used to propagate this information.+For example, a tactic that solves the current goal when it is the unit type might look like this:++.. code-block:: idris++    triv : Elab ()+    triv = do compute+              g <- getGoal+              case (snd g) of+                `(() : Type) => do fill `(() : ())+                                   solve+                otherGoal => fail [ TermPart otherGoal+                                  , TextPart "is not trivial"+                                  ]+++The tactic ``compute`` normalises the type of its goal with respect to the current context.+While not strictly necessary, this allows ``triv`` to be used in contexts where the triviality of the goal is not immediately apparent.+Then, ``getGoal`` is used, and its result is bound to ``g``.+Because it returns a pair consisting of the current goal's name and type, we case-split on its second projection.+If the goal type turns out to have been the unit type, we fill using the unit constructor and solve the goal.+Otherwise, we fail with an error message informing the user that the current goal is not trivial.++Additionally, the elaboration state can be dumped into an error message with the ``debug`` tactic.+A variant, ``debugMessage``, allows arbitrary messages to be included with the state, allowing for a kind of "``printf`` debugging" of elaboration scripts.+The message format used by ``debugMessage`` is the same for errors produced by the error reflection mechanism, allowing the re-use of the Idris pretty-printer when rendering messages.++Changing the Global Context+===========================++``Elab`` scripts can modify the global context during execution.+Just as the Idris elaborator produces auxiliary definitions to implement features such as ``where``-blocks and ``case`` expressions, user elaboration scripts may need to define functions.+Furthermore, this allows ``Elab`` reflection to be used to implement features such as interface deriving.+The operations ``declareType``, ``defineFunction``, and ``addImplementation`` allow ``Elab`` scripts to modify the global context.++Using Idris's Features+======================++The Idris compiler has a number of ways to automate the construction of terms.+On its own, the ``Elab`` state and its interactions with the unifier allow implicits to be solved using unification.+Additional operations use further features of Idris.+In particular, ``resolveTC`` solves the current goal using interface resolution, ``search`` invokes the proof search mechanism, and ``sourceLocation`` finds the context in the original file at which the elaboration script is invoked.+++Recursive Elaboration+=====================++The elaboration mechanism can be invoked recursively using the ``runElab`` tactic.+This tactic takes a goal type and an elaboration script as arguments and runs the script in a fresh lexical environment to create an inhabitant of the provided goal type.+This is primarily useful for code generation, particularly for generating pattern-matching clauses, where variable scope needs to be one that isn't the present local context.++Learn More+==========+While this documentation is still incomplete, elaboration reflection works in Idris today.+As you wait for the completion of the documentation, the list of built-in tactics can be obtained using the ``:browse`` command in an Idris REPL or the corresponding feature in one of the graphical IDE clients to explore the ``Language.Reflection.Elab.Tactics`` namespace.+All of the built-in tactics contain documentation strings.
+ docs/reference/erasure.rst view
@@ -0,0 +1,502 @@+*************************+Erasure By Usage Analysis+*************************++This work stems from this `feature proposal+<https://github.com/idris-lang/Idris-dev/wiki/Egg-%232%3A-Erasure-annotations>`__+(obsoleted by this page). Beware that the information in the proposal+is out of date — and sometimes even in direct contradiction with the+eventual implementation.++Motivation+==========++Traditional dependently typed languages (Agda, Coq) are good at+erasing *proofs* (either via irrelevance or an extra universe).++.. code-block:: idris++    half : (n : Nat) -> Even n -> Nat+    half Z EZ = Z+    half (S (S n)) (ES pf) = S (half n pf)++For example, in the above snippet, the second argument is a proof,+which is used only to convince the compiler that the function is+total. This proof is never inspected at runtime and thus can be+erased. In this case, the mere existence of the proof is sufficient+and we can use irrelevance-related methods to achieve erasure.++However, sometimes we want to erase *indices* and this is where the+traditional approaches stop being useful, mainly for reasons described+in the `original proposal+<https://github.com/idris-lang/Idris-dev/wiki/Egg-%232%3A-Erasure-annotations>`__.++.. code-block:: idris++    uninterleave : {n : Nat} -> Vect (n * 2) a -> (Vect n a, Vect n a)+    uninterleave [] = ([] , [])+    uninterleave (x :: y :: rest) with (unzipPairs rest)+      | (xs, ys) = (x :: xs, y :: ys)++Notice that in this case, the second argument is the important one and+we would like to get rid of the ``n`` instead, although the shape of+the program is generally the same as in the previous case.++There are methods described by Brady, McBride and McKinna in [BMM04]_+to remove the indices from data structures, exploiting the fact that+functions operating on them either already have a copy of the+appropriate index or the index can be quickly reconstructed if needed.+However, we often want to erase the indices altogether, from the whole+program, even in those cases where reconstruction is not possible.++The following two sections describe two cases where doing so improves+the runtime performance asymptotically.++Binary numbers+--------------++- O(n) instead of O(log n)++Consider the following ``Nat``-indexed type family representing binary+numbers:++.. code-block:: idris++    data Bin : Nat -> Type where+      N : Bin 0+      O : {n : Nat} -> Bin n -> Bin (0 + 2*n)+      I : {n : Nat} -> Bin n -> Bin (1 + 2*n)++These are supposed to be (at least asymptotically) fast and+memory-efficient because their size is logarithmic compared to the+numbers they represent.++Unfortunately this is not the case. The problem is that these binary+numbers still carry the *unary* indices with them, performing+arithmetic on the indices whenever arithmetic is done on the binary+numbers themselves. Hence the real representation of the number 15+looks like this:++::++    I -> I -> I -> I -> N+    S    S    S    Z+    S    S    Z+    S    S+    S    Z+    S+    S+    S+    Z++The used memory is actually *linear*, not logarithmic and therefore we+cannot get below O(n) with time complexities.++One could argue that Idris in fact compiles ``Nat`` via GMP but+that's a moot point for two reasons:+++ First, whenever we try to index our data structures with anything+  else than ``Nat``, the compiler is not going to come to the rescue.+++ Second, even with ``Nat``, the GMP integers are *still* there and+  they slow the runtime down.++This ought not to be the case since the ``Nat`` are never used at+runtime and they are only there for typechecking purposes. Hence we+should get rid of them and get runtime code similar to what a idris+programmer would write.++U-views of lists+----------------++-  O(n^2) instead of O(n)++Consider the type of U-views of lists:++.. code-block:: idris++    data U : List a -> Type where+      nil : U []+      one : (z : a) -> U [z]+      two : {xs : List a} -> (x : a) -> (u : U xs) -> (y : a) -> U (x :: xs ++ [y])++For better intuition, the shape of the U-view of+``[x0,x1,x2,z,y2,y1,y0]`` looks like this:++::++      x0   y0    (two)+      x1   y1    (two)+      x2   y1    (two)+         z       (one)++When recursing over this structure, the values of ``xs`` range over+``[x0,x1,x2,z,y2,y1,y0]``, ``[x1,x2,z,y2,y1]``, ``[x2,z,y2]``,+``[z]``.  No matter whether these lists are stored or built on demand,+they take up a quadratic amount of memory (because they cannot share+nodes), and hence it takes a quadratic amount of time just to build+values of this index alone.++But the reasonable expectation is that operations with U-views take+linear time — so we need to erase the index ``xs`` if we want to+achieve this goal.++Changes to Idris+================++Usage analysis is run at every compilation and its outputs are used+for various purposes. This is actually invisible to the user but it's+a relatively big and important change, which enables the new features.++Everything that is found to be unused is erased. No annotations are+needed, just don't use the thing and it will vanish from the generated+code. However, if you wish, you can use the dot annotations to get a+warning if the thing is accidentally used.++"Being used" in this context means that the value of the "thing" may+influence run-time behaviour of the program. (More precisely, it is+not found to be irrelevant to the run-time behaviour by the usage+analysis algorithm.)++"Things" considered for removal by erasure include:++* function arguments++* data constructor fields (including record fields and dictionary+  fields of interface implementations)++For example, ``Either`` often compiles to the same runtime+representation as ``Bool``. Constructor field removal sometimes+combines with the newtype optimisation to have quite a strong effect.++There is a new compiler option ``--warnreach``, which will enable+warnings coming from erasure. Since we have full usage analysis, we+can compile even those programs that violate erasure annotations --+it's just that the binaries may run slower than expected. The warnings+will be enabled by default in future versions of Idris (and possibly+turned to errors). However, in this transitional period, we chose to+keep them on-demand to avoid confusion until better documentation is+written.++Case-tree elaboration tries to avoid using dotted "things" whenever+possible. (NB. This is not yet perfect and it's being worked on:+https://gist.github.com/ziman/10458331)++Postulates are no longer required to be collapsible. They are now+required to be *unused* instead.++Changes to the language+=======================++You can use dots to mark fields that are not intended to be used at+runtime.++.. code-block:: idris++    data Bin : Nat -> Type where+      N : Bin 0+      O : .{n : Nat} -> Bin n -> Bin (0 + 2*n)+      I : .{n : Nat} -> Bin n -> Bin (1 + 2*n)++If these fields are found to be used at runtime, the dots will trigger+a warning (with ``--warnreach``).++Note that free (unbound) implicits are dotted by default so, for+example, the constructor ``O`` can be defined as:++.. code-block:: idris++      O : Bin n -> Bin (0 + 2*n)++and this is actually the preferred form.++If you have a free implicit which is meant to be used at runtime, you+have to change it into an (undotted) ``{bound : implicit}``.++You can also put dots in types of functions to get more guarantees.++.. code-block:: idris++    half : (n : Nat) -> .(pf : Even n) -> Nat++and free implicits are automatically dotted here, too.++What it means+=============++Dot annotations serve two purposes:++* influence case-tree elaboration to avoid dotted variables++* trigger warnings when a dotted variable is used++However, there's no direct connection between being dotted and being+erased. The compiler erases everything it can, dotted or not. The dots+are there mainly to help the programmer (and the compiler) refrain+from using the values they want to erase.++How to use it+=============++Ideally, few or no extra annotations are needed -- in practice, it+turns out that having free implicits automatically dotted is enough to+get good erasure.++Therefore, just compile with ``--warnreach`` to see warnings if+erasure cannot remove parts of the program.++However, those programs that have been written without runtime+behaviour in mind, will need some help to get in the form that+compiles to a reasonable binary. Generally, it's sufficient to follow+erasure warnings (which may be sometimes unhelpful at the moment).++Benchmarks+==========++-  source: https://github.com/ziman/idris-benchmarks+-  results: http://ziman.functor.sk/erasure-bm/++It can be clearly seen that asymptotics are improved by erasure.++Shortcomings+============++You can't get warnings in libraries because usage analysis starts from+``Main.main``. This will be solved by the planned ``%default_usage``+pragma.++Usage warnings are quite bad and unhelpful at the moment. We should+include more information and at least translate argument numbers to+their names.++There is no decent documentation yet. This wiki page is the first one.++There is no generally accepted terminology. We switch between+"dotted", "unused", "erased", "irrelevant", "inaccessible", while each+has a slightly different meaning. We need more consistent and+understandable naming.++If the same type is used in both erased and non-erased context, it+will retain its fields to accommodate the least common denominator --+the non-erased context. This is particularly troublesome in the case+of the type of (dependent) pairs, where it actually means that no+erasure would be performed. We should probably locate disjoint uses of+data types and split them into "sub-types". There are three different+flavours of dependent types now: ``Sigma`` (nothing erased),+``Exists`` (first component erased), ``Subset`` (second component+erased).++Case-tree building does not avoid dotted values coming from+pattern-matched constructors (https://gist.github.com/ziman/10458331).+This is to be fixed soon. (Fixed.)++Higher-order function arguments and opaque functional variables are+considered to be using all their arguments. To work around this, you+can force erasure via the type system, using the ``Erased`` wrapper:+https://github.com/idris-lang/Idris-dev/blob/master/libs/base/Data/Erased.idr++Interface methods are considered to be using the union of all their+implementations. In other words, an argument of a method is unused+only if it is unused in every implementation of the method that occurs+in the program.++Planned features+================++- Fixes to the above shortcomings in general.++- Improvements to the case-tree elaborator so that it properly avoids+   dotted fields of data constructors. Done.++- Compiler pragma ``%default_usage used/unused`` and per-function+   overrides ``used`` and ``unused``, which allow the programmer to+   mark the return value of a function as used, even if the function+   is not used in ``main`` (which is the case when writing library+   code). These annotations will help library writers discover usage+   violations in their code before it is actually published and used+   in compiled programs.++Troubleshooting+===============++My program is slower+--------------------++The patch introducing erasure by usage analysis also disabled some+optimisations that were in place before; these are subsumed by the new+erasure. However, in some erasure-unaware programs, where erasure by+usage analysis does not exercise its full potential (but the old+optimisations would have worked), certain slowdown may be observed (up+to ~10% according to preliminary benchmarking), due to retention and+computation of information that should not be necessary at runtime.++A simple check whether this is the case is to compile with+``--warnreach``. If you see warnings, there is some unnecessary code+getting compiled into the binary.++The solution is to change the code so that there are no warnings.++Usage warnings are unhelpful+----------------------------++This is a known issue and we are working on it. For now, see the section+`How to read and resolve erasure+warnings <#how-to-read-and-resolve-erasure-warnings>`__.++There should be no warnings in this function+--------------------------------------------++A possible cause is non-totality of the function (more precisely,+non-coverage). If a function is non-covering, the program needs to+inspect all arguments in order to detect coverage failures at runtime.+Since the function inspects all its arguments, nothing can be erased+and this may transitively cause usage violations. The solution is to+make the function total or accept the fact that it will use its+arguments and remove some dots from the appropriate constructor fields+and function arguments. (Please note that this is not a shortcoming of+erasure and there is nothing we can do about it.)++Another possible cause is the currently imperfect case-tree+elaboration, which does not avoid dotted constructor fields (see+https://gist.github.com/ziman/10458331). You can either rephrase the+function or wait until this is fixed, hopefully soon. Fixed.++The compiler refuses to recognise this thing as erased+------------------------------------------------------++You can force anything to be erased by wrapping it in the ``Erased``+monad. While this program triggers usage warnings,++.. code-block:: idris++    f : (g : Nat -> Nat) -> .(x : Nat) -> Nat+    f g x = g x  -- WARNING: g uses x++the following program does not:++.. code-block:: idris++    f : (g : Erased Nat -> Nat) -> .(x : Nat) -> Nat+    f g x = g (Erase x)  -- OK++How to read and resolve erasure warnings+========================================++Example 1+---------++Consider the following program:++.. code-block:: idris++    vlen : Vect n a -> Nat+    vlen {n = n} xs = n++    sumLengths : List (Vect n a) -> Nat+    sumLengths       []  = 0+    sumLengths (v :: vs) = vlen v + sumLengths vs++    main : IO ()+    main = print . sumLengths $ [[0,1],[2,3]]++When you compile it using ``--warnreach``, there is one warning:++.. code-block:: idris++    Main.sumLengths: inaccessible arguments reachable:+      n (no more information available)++The warning does not contain much detail at this point so we can try+compiling with ``--dumpcases cases.txt`` and look up the compiled+definition in ``cases.txt``:++.. code-block:: idris++    Main.sumLengths {e0} {e1} {e2} =+      case {e2} of+      | Prelude.List.::({e6}) => LPlus (ATInt ITBig)({e0}, Main.sumLengths({e0}, ____, {e6}))+      | Prelude.List.Nil() => 0++The reason for the warning is that ``sumLengths`` calls ``vlen``, which+gets inlined. The second clause of ``sumLengths`` then accesses the+variable ``n``, compiled as ``{e0}``. Since ``n`` is a free implicit, it+is automatically considered dotted and this triggers the warning.++A solution would be either making the argument ``n`` a bound implicit+parameter to indicate that we wish to keep it at runtime,++.. code-block:: idris++    sumLengths : {n : Nat} -> List (Vect n a) -> Nat++or fixing ``vlen`` to not use the index:++.. code-block:: idris++    vlen : Vect n a -> Nat+    vlen [] = Z+    vlen (x :: xs) = S (vlen xs)++Which solution is appropriate depends on the usecase.++Example 2+---------++Consider the following program manipulating value-indexed binary+numbers.++.. code-block:: idris++    data Bin : Nat -> Type where+        N : Bin Z+        O : Bin n -> Bin (0 + n + n)+        I : Bin n -> Bin (1 + n + n)++    toN : (b : Bin n) -> Nat+    toN  N = Z+    toN (O {n} bs) = 0 + n + n+    toN (I {n} bs) = 1 + n + n++    main : IO ()+    main = print . toN $ I (I (O (O (I N))))++In the function ``toN``, we attempted to "cheat" and instead of+traversing the whole structure, we just projected the value index ``n``+out of constructors ``I`` and ``O``. However, this index is a free+implicit, therefore it is considered dotted.++Inspecting it then produces the following warnings when compiling with+``--warnreach``:++.. code-block:: idris++    Main.I: inaccessible arguments reachable:+      n from Main.toN arg# 1+    Main.O: inaccessible arguments reachable:+      n from Main.toN arg# 1++We can see that the argument ``n`` of both ``I`` and ``O`` is used in+the function ``toN``, argument 1.++At this stage of development, warnings only contain argument numbers,+not names; this will hopefully be fixed. When numbering arguments, we+go from 0, taking free implicits first, left-to-right; then the bound+arguments. The function ``toN`` has therefore in fact two arguments:+``n`` (argument 0) and ``b`` (argument 1). And indeed, as the warning+says, we project the dotted field from ``b``.++Again, one solution is to fix the function ``toN`` to calculate its+result honestly; the other one is to accept that we carry a ``Nat``+with every constructor of ``Bin`` and make it a bound implicit:++.. code-block:: idris++        O : {n : Nat} -> Bin n -> Bin (0 + n + n)+        I : {n : Nat} -> bin n -> Bin (1 + n + n)++References+==========++.. [BMM04] Edwin Brady, Conor McBride, James McKinna: `Inductive+           families need not store their indices+           <http://citeseerx.ist.psu.edu/viewdoc/summary;jsessionid=1F796FCF0F2C4C535FC70F62BE2FB821?doi=10.1.1.62.3849>`__
+ docs/reference/ffi.rst view
@@ -0,0 +1,364 @@+******************************+New Foreign Function Interface+******************************++.. sectionauthor:: Edwin Brady++Ever since Idris has had multiple backends compiling to different+target languages on potentially different platforms, we have had the+problem that the foreign function interface (FFI) was written under+the assumption of compiling to C. As a result, it has been hard to+write generic code for multiple targets, or even to be sure that if+code compiles that it will run on the expected target.++As of 0.9.17, Idris will have a new foreign function interface (FFI)+which is aware of multiple targets. Users who are working with the+default code generator can happily continue writing programs as before+with no changes, but if you are writing bindings for an external+library, writing a back end, or working with a non-C back end, there+are some things you will need to be aware of, which this page+describes.++The ``IO'`` monad, and ``main``+===============================++The ``IO`` monad exists as before, but is now specific to the C+backend (or, more precisely, any backend whose foreign function calls+are compatible with C.) Additionally, there is now an ``IO'`` monad,+which is parameterised over a FFI descriptor:++.. code-block:: idris++    data IO' : (lang : FFI) -> Type -> Type++The Prelude defines two FFI descriptors which are imported+automatically, for C and JavaScript/Node, and defines ``IO`` to use+the C FFI and ``JS_IO`` to use the JavaScript FFI:++.. code-block:: idris++    FFI_C  : FFI+    FFI_JS : FFI++    IO : Type -> Type+    IO a = IO' FFI_C a++    JS_IO : Type -> Type+    JS_IO a = IO' FFI_JS a++As before, the entry point to an Idris program is ``main``, but the+type of ``main`` can now be any implementation of ``IO'``, e.g. the+following are both valid:++.. code-block:: idris++    main : IO ()+    main : JS_IO ()++The FFI descriptor includes details about which types can be+marshalled between the foreign language and Idris, and the "target" of+a foreign function call (typically just a String representation of the+function's name, but potentially something more complicated such as an+external library file or even a URL).++FFI descriptors+===============++An FFI descriptor is a record containing a predicate which holds when+a type can be marshalled, and the type of the target of a foreign+call:++.. code-block:: idris++    record FFI where+         constructor MkFFI+         ffi_types : Type -> Type+         ffi_fn : Type++For C, this is:++.. code-block:: idris++    ||| Supported C integer types+    public export+    data C_IntTypes : Type -> Type where+        C_IntChar   : C_IntTypes Char+        C_IntNative : C_IntTypes Int+        C_IntBits8  : C_IntTypes Bits8+        C_IntBits16 : C_IntTypes Bits16+        C_IntBits32 : C_IntTypes Bits32+        C_IntBits64 : C_IntTypes Bits64++    ||| Supported C function types+    public export+    data C_FnTypes : Type -> Type where+        C_Fn : C_Types s -> C_FnTypes t -> C_FnTypes (s -> t)+        C_FnIO : C_Types t -> C_FnTypes (IO' FFI_C t)+        C_FnBase : C_Types t -> C_FnTypes t++    ||| Supported C foreign types+    public export+    data C_Types : Type -> Type where+        C_Str   : C_Types String+        C_Float : C_Types Double+        C_Ptr   : C_Types Ptr+        C_MPtr  : C_Types ManagedPtr+        C_Unit  : C_Types ()+        C_Any   : C_Types (Raw a)+        C_FnT   : C_FnTypes t -> C_Types (CFnPtr t)+        C_IntT  : C_IntTypes i -> C_Types i++    ||| A descriptor for the C FFI. See the constructors of `C_Types`+    ||| and `C_IntTypes` for the concrete types that are available.+    %error_reverse+    public export+    FFI_C : FFI+        FFI_C = MkFFI C_Types String String++Foreign calls+=============++To call a foreign function, the ``foreign`` function is used. For+example:++.. code-block:: idris++    do_fopen : String -> String -> IO Ptr+    do_fopen f m+       = foreign FFI_C "fileOpen" (String -> String -> IO Ptr) f m++The ``foreign`` function takes an FFI description, a function name (the+type is given by the ``ffi_fn`` field of ``FFI_C`` here), and a function+type, which gives the expected types of the remaining arguments. Here,+we're calling an external function ``fileOpen`` which takes, in the C, a+``char*`` file name, a ``char*`` mode, and returns a file pointer. It is+the job of the C back end to convert Idris ``String`` to C ``char*``+and vice versa.++The argument types and return type given here must be present in the+``fn_types`` predicate of the ``FFI_C`` description for the foreign+call to be valid.++**Note** The arguments to ``foreign`` *must* be known at compile time,+because the foreign calls are generated statically. The ``%inline``+directive on a function can be used to give hints to help this, for+example a shorthand for calling external JavaScript functions:++.. code-block:: idris++    %inline+    jscall : (fname : String) -> (ty : Type) ->+              {auto fty : FTy FFI_JS [] ty} -> ty+    jscall fname ty = foreign FFI_JS fname ty++C callbacks+-----------+It is possible to pass an Idris function to a C function taking a function+pointer by using ``CFnPtr`` in the function type. The Idris function is passed+to ``MkCFnPtr`` in the arguments. The example below shows declaring the C standard+library function ``qsort`` which takes a pointer to a comparison function.++.. code-block:: idris++    myComparer : Ptr -> Ptr -> Int+    myComparer = ...++    qsort : Ptr -> Int -> Int -> IO ()+    test2 data elems elsize = foreign FFI_C "qsort"+                    (Ptr -> Int -> Int -> CFnPtr (Ptr -> Ptr -> Int) -> IO ())+                    data elems elsize (MkCFnPtr myComparer)++There are a few limitations to callbacks in the C FFI. The foreign function can't+take the function to make a callback of as an argument. This will give a+compilation error:++.. code-block:: idris++    -- This does not work+    example : (Int -> ()) -> IO ()+    example f = foreign FFI_C "callbacker" (CFnPtr (Int -> ()) -> IO ()) f++The other big limitation is that it doesn't support IO functions. Use+``unsafePerformIO`` to wrap them (i.e. to make an IO function usable as a callback, change the return type+from IOr to r, and change the = do to = unsafePerformIO $ do).++There are two special function names:+``%wrapper`` returns the function pointer that wraps an Idris function. This+is useful if the function pointer isn't taken by a C function directly but+should be inserted into a data structure. A foreign declaration using+``%wrapper`` must return ``IO Ptr``.++.. code-block:: idris++    -- this returns the C function pointer to a qsort comparer+    example_wrapper : IO Ptr+    example_wrapper = foreign FFI_C "%wrapper" (CFnPtr (Ptr -> Ptr -> Int) -> IO Ptr)+                            (MkCFnPtr myComparer)++``%dynamic`` calls a C function pointer with some arguments. This is useful if+a C function returns or data structure contains a C function pointer, for example+structs of function pointers are common in object-oriented C such as in COM or the+Linux kernel. The function type contains an extra ``Ptr`` at the start for the+function pointer. ``%dynamic`` can be seen as a pseudo-function that calls the+function in the first argument, passing the remaining arguments to it.++.. code-block:: idris++    -- we have a pointer to a function with the signature int f(int), call it+    example_dynamic : Ptr -> Int -> IO Int+    example_dynamic fn x = foreign FFI_C "%dynamic" (Ptr -> Int -> IO Int) fn x++If the foreign name is prefixed by a ``&``, it is treated as a pointer to the+global variable with the following name. The type must be just ``IO Ptr``.++.. code-block:: idris++    -- access the global variable errno+    errno : IO Ptr+    errno = foreign FFI_C "&errno" (IO Ptr)++For more complicated interactions with C (such as reading and setting fields of a C struct), there is+a module CFFI available in the contrib package.++FFI implementation+------------------++In order to write bindings to external libraries, the details of how+``foreign`` works are unnecessary --- you simply need to know that+``foreign`` takes an FFI descriptor, the function name, and its+type. It is instructive to look a little deeper, however:++The type of ``foreign`` is as follows:++.. code-block:: idris++    foreign : (ffi : FFI)+           -> (fname : ffi_fn f)+           -> (ty : Type)+           -> {auto fty : FTy ffi [] ty}+           -> ty++The important argument here is the implicit ``fty``, which contains a+proof (``FTy``) that the given type is valid according to the FFI+description ``ffi``:++.. code-block:: idris++    data FTy : FFI -> List Type -> Type -> Type where+         FRet : ffi_types f t -> FTy f xs (IO' f t)+         FFun : ffi_types f s -> FTy f (s :: xs) t -> FTy f xs (s -> t)++Notice that this uses the ``ffi_types`` field of the FFI descriptor+--- these arguments to ``FRet`` and ``FFun`` give explicit proofs that+the type is valid in this FFI. For example, the above ``do_fopen``+builds the following implicit proof as the ``fty`` argument to+``foreign``:++.. code-block:: idris++    FFun C_Str (FFun C_Str (FRet C_Ptr))++Compiling foreign calls+=======================++(This section assumes some knowledge of the Idris internals.)++When writing a back end, we now need to know how to compile+``foreign``.  We'll skip the details here of how a ``foreign`` call+reaches the intermediate representation (the IR), though you can look+in ``IO.idr`` in the ``prelude`` package to see a bit more detail ---+a ``foreign`` call is implemented by the primitive function+``mkForeignPrim``. The important part of the IR as defined in+``Lang.hs`` is the following constructor:++.. code-block:: idris++    data LExp = ...+              | LForeign FDesc -- Function descriptor+                         FDesc -- Return type descriptor+                         [(FDesc, LExp)]++So, a ``foreign`` call appears in the IR as the ``LForeign``+constructor, which takes a function descriptor (of a type given by the+``ffi_fn`` field in the FFI descriptor), a return type descriptor+(given by an application of ``FTy``), and a list of arguments with+type descriptors (also given by an application of ``FTy``).++An ``FDesc`` describes an application of a name to some arguments, and+is really just a simplified subset of an ``LExp``:++.. code-block:: idris++    data FDesc = FCon Name+               | FStr String+               | FUnknown+               | FApp Name [FDesc]++There are corresponding structures in the lower level IRs, such as the+defunctionalised, simplified and bytecode forms.++Our ``do_fopen`` example above arrives in the ``LExp`` form as:++.. code-block:: idris++    LForeign (FStr "fileOpen") (FCon (sUN "C_Ptr"))+             [(FCon (sUN "C_Str"), f), (FCon (sUN "C_Str"), m)]++(Assuming that ``f`` and ``m`` stand for the ``LExp`` representations+of the arguments.) This information should be enough for any back end+to marshal the arguments and return value appropriately.++.. note::++   When processing ``FDesc``, be aware that there may be implicit+   arguments, which have not been erased. For example, ``C_IntT`` has+   an implicit argument ``i``, so will appear in an ``FDesc`` as+   something of the form ``FApp (sUN "C_IntT") [i, t]`` where ``i`` is+   the implicit argument (which can be ignored) and ``t`` is the+   descriptor of the integer type. See ``CodegenC.hs``, specifically+   the function ``toFType``, to see how this works in practice.++JavaScript FFI descriptor+=========================++The JavaScript FFI descriptor is a little more complex, because the+JavaScript FFI supports marshalling functions. It is defined as+follows:++.. code-block:: idris++    mutual+      data JsFn t = MkJsFn t++      data JS_IntTypes  : Type -> Type where+           JS_IntChar   : JS_IntTypes Char+           JS_IntNative : JS_IntTypes Int++      data JS_FnTypes : Type -> Type where+           JS_Fn     : JS_Types s -> JS_FnTypes t -> JS_FnTypes (s -> t)+           JS_FnIO   : JS_Types t -> JS_FnTypes (IO' l t)+           JS_FnBase : JS_Types t -> JS_FnTypes t++      data JS_Types : Type -> Type where+           JS_Str   : JS_Types String+           JS_Float : JS_Types Double+           JS_Ptr   : JS_Types Ptr+           JS_Unit  : JS_Types ()+           JS_FnT   : JS_FnTypes a -> JS_Types (JsFn a)+           JS_IntT  : JS_IntTypes i -> JS_Types i++The reason for wrapping function types in a ``JsFn`` is to help the+proof search when building ``FTy``. We hope to improve proof search+eventually, but for the moment it works much more reliably if the+indices are disjoint! An example of using this appears in `IdrisScript+<https://github.com/idris-hackers/IdrisScript>`__ when setting+timeouts:++.. code-block:: idris++    setTimeout : (() -> JS_IO ()) -> (millis : Int) -> JS_IO Timeout+    setTimeout f millis = do+      timeout <- jscall "setTimeout(%0, %1)"+                        (JsFn (() -> JS_IO ()) -> Int -> JS_IO Ptr)+                        (MkJsFn f) millis+      return $ MkTimeout timeout
+ docs/reference/ide-protocol.rst view
@@ -0,0 +1,213 @@+********************+The IDE Protocol+********************++The Idris REPL has two modes of interaction: a human-readable syntax designed for direct use in a terminal, and a machine-readable syntax designed for using Idris as a backend for external tools.++Protocol Overview+-----------------++The communication protocol is of asynchronous request-reply style: a single request from the client is handled by Idris at a time.+Idris waits for a request on its standard input stream, and outputs the answer or answers to standard output.+The result of a request can be either success, failure, or intermediate output; and furthermore, before the result is delivered, there might be additional meta-messages.+++A reply can consist of multiple messages: any number of messages to inform the user about the progress of the request or other informational output, and finally a result, either ``ok`` or ``error``.++The wire format is the length of the message in characters, encoded in 6 characters hexadecimal, followed by the message encoded as S-expression (sexp).+Additionally, each request includes a unique integer (counting upwards), which is repeated in all messages corresponding to that request.++An example interaction from loading the file ``/home/hannes/empty.idr`` looks as follows on the wire:::++  00002a((:load-file "/home/hannes/empty.idr") 1)+  000039(:write-string "Type checking /home/hannes/empty.idr" 1)+  000025(:set-prompt "/home/hannes/empty" 1)+  000032(:return (:ok "Loaded /home/hannes/empty.idr") 1)+++The first message is the request from idris-mode to load the specific file, which length is hex 2a, decimal 42 (including the newline at the end).+The request identifier is set to 1.+The first message from Idris is to write the string ``Type checking /home/hannes/empty.idr``, another is to set the prompt to ``*/home/hannes/empty``.+The answer, starting with ``:return`` is ``ok``, and additional information is that the file was loaded.++There are three atoms in the wire language: numbers, strings, and symbols.+The only compound object is a list, which is surrounded by parenthesis.+The syntax is::++  A ::= NUM | '"' STR '"' | ':' ALPHA++  S ::= A | '(' S* ')' | nil++where ``NUM`` is either 0 or a positive integer, ``ALPHA`` is an alphabetical character, and ``STR`` is the contents of a string, with ``"`` escaped by a backslash.+The atom ``nil`` is accepted instead of ``()`` for compatibility with some regexp pretty-printing routines.++The state of the Idris process is mainly the active file, which needs to be kept synchronised between the editor and Idris.+This is achieved by the already seen ``:load-file`` command.++The available commands include:++  ``(:load-file FILENAME)``+    Load the named file.++  ``(:interpret STRING)``+    Interpret ``STRING`` at the Idris REPL, returning a highlighted result.++  ``(:repl-completions STRING)``+    Return the result of tab-completing ``STRING`` as a REPL command.++  ``(:type-of STRING)``+    Return the type of the name, written with Idris syntax in the ``STRING``.+    The reply may contain highlighting information.++  ``(:case-split LINE NAME)``+    Generate a case-split for the pattern variable ``NAME`` on program line ``LINE``.+    The pattern-match cases to be substituted are returned as a string with no highlighting.++  ``(:add-clause LINE NAME)``+    Generate an initial pattern-match clause for the function declared as ``NAME`` on program line ``LINE``.+    The initial clause is returned as a string with no highlighting.++  ``(:add-proof-clause LINE NAME)``+    Add a clause driven by the ``<==`` syntax.++  ``(:add-missing LINE NAME)``+    Add the missing cases discovered by totality checking the function declared as ``NAME`` on program line ``LINE``.+    The missing clauses are returned as a string with no highlighting.++  ``(:make-with LINE NAME)``+    Create a with-rule pattern match template for the clause of function ``NAME`` on line ``LINE``.+    The new code is returned with no highlighting.++  ``(:make-case LINE NAME)``+    Create a case pattern match template for the clause of function ``NAME`` on line ``LINE``.+    The new code is returned with no highlighting.++  ``(:make-lemma LINE NAME)``+    Create a top level function with a type which solves the hole named ``NAME`` on line ``LINE``.++  ``(:proof-search LINE NAME HINTS)``+    Attempt to fill out the holes on ``LINE`` named ``NAME`` by proof search.+    ``HINTS`` is a possibly-empty list of additional things to try while searching.++  ``(:docs-for NAME)``+    Look up the documentation for ``NAME``, and return it as a highlighted string.++  ``(:metavariables WIDTH)``+    List the currently-active holes, with their types pretty-printed with ``WIDTH`` columns.++  ``(:who-calls NAME)``+    Get a list of callers of ``NAME``.++  ``(:calls-who NAME)``+    Get a list of callees of ``NAME``.++  ``(:browse-namespace NAMESPACE)``+    Return the contents of ``NAMESPACE``, like ``:browse`` at the command-line REPL.++  ``(:normalise-term TM)``+    Return a highlighted string consisting of the results of normalising the serialised term ``TM`` (which would previously have been sent as the ``tt-term`` property of a string).++  ``(:show-term-implicits TM)``+    Return a highlighted string consisting of the results of making all arguments in serialised term ``TM`` (which would previously have been sent as the ``tt-term`` property of a string) explicit.++  ``(:hide-term-implicits TM)``+    Return a highlighted string consisting of the results of making all arguments in serialised term ``TM`` (which would previously have been sent as the ``tt-term`` property of a string) follow their usual implicitness setting.++  ``(:elaborate-term TM)``+    Return a highlighted string consisting of the the core language term corresponding to serialised term ``TM`` (which would previously have been sent as the ``tt-term`` property of a string).++  ``(:print-definition NAME)``+    Return the definition of ``NAME`` as a highlighted string.++  ``(:repl-completions NAME)``+    Search names, types and documentations which contain ``NAME``.++  ``(:version UID)``+    Return the version information of the Idris compiler.++++Possible replies include a normal final reply:::++ (:return (:ok SEXP [HIGHLIGHTING]))+ (:return (:error String [HIGHLIGHTING]))++A normal intermediate reply:::++ (:output (:ok SEXP [HIGHLIGHTING]))+ (:output (:error String [HIGHLIGHTING]))++Informational and/or abnormal replies:::++  (:write-string String)+  (:set-prompt String)+  (:warning (FilePath (LINE COL) (LINE COL) String [HIGHLIGHTING]))++Proof mode replies:::++  (:start-proof-mode)+  (:write-proof-state [String] [HIGHLIGHTING])+  (:end-proof-mode)+  (:write-goal String)++Output Highlighting+-------------------++Idris mode supports highlighting the output from Idris.+In reality, this highlighting is controlled by the Idris compiler.+Some of the return forms from Idris support an optional extra parameter: a list mapping spans of text to metadata about that text.+Clients can then use this list both to highlight the displayed output and to enable richer interaction by having more metadata present.+For example, the Emacs mode allows right-clicking identifiers to get a menu with access to documentation and type signatures.+++A particular semantic span is a three element list.+The first element of the list is the index at which the span begins, the second element is the number of characters included in the span, and the third is the semantic data itself.+The semantic data is a list of lists.+The head of each list is a key that denotes what kind of metadata is in the list, and the tail is the metadata itself.++The following keys are available:+  ``name``+    gives a reference to the fully-qualified Idris name+  ``implicit``+    provides a Boolean value that is True if the region is the name of an implicit argument+  ``decor``+    describes the category of a token, which can be ``type``, ``function``, ``data``, ``keyword``, or ``bound``.++  ``source-loc``+    states that the region refers to a source code location. Its body is a collection of key-value pairs, with the following possibilities:++    ``filename``+      provides the filename++    ``start``+      provides the line and column that the source location starts at as a two-element tail++    ``end``+      provides the line and column that the source location ends at as a two-element tail++  ``text-formatting``+    provides an attribute of formatted text. This is for use with natural-language text, not code, and is presently emitted only from inline documentation. The potential values are ``bold``, ``italic``, and ``underline``.++  ``link-href``+    provides a URL that the corresponding text is a link to. ++  ``quasiquotation``+    states that the region is quasiquoted.++  ``antiquotation``+    states that the region is antiquoted.++  ``tt-term``+    A serialised representation of the Idris core term corresponding to the region of text.++Source Code Highlighting+------------------------++Idris supports instructing editors how to colour their code.+When elaborating source code or REPL input, Idris will locate regions of the source code corresponding to names, and emit information about these names using the same metadata as output highlighting.++These messages will arrive as replies to the command that caused elaboration to occur, such as ``:load-file`` or ``:interpret``.+They have the format:::++  (:output (:ok (:highlight-source POSNS)))++where ``POSNS`` is a list of positions to highlight. Each of these is a two-element list whose first element is a position (encoded as for the ``source-loc`` property above) and whose second element is highlighting metadata in the same format used for output.
+ docs/reference/index.rst view
@@ -0,0 +1,41 @@+.. _reference-index:++###################+Language Reference+###################++This is the reference guide for the Idris Language.+It documents the language specification and internals.+This will tell you how Idris works, for using it you should read the Idris Tutorial.++.. note::+   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/+++.. toctree::+   :maxdepth: 1++   codegen+   documenting+   packages+   uniqueness-types+   ffi+   syntax-guide+   erasure+   ide-protocol+   semantic-highlighting+   tactics+   repl+   compilation+   internals+   language-features+   language-extensions+   elaborator-reflection+   type-directed-search+   partial-evaluation+   misc
+ docs/reference/internals.rst view
@@ -0,0 +1,176 @@+*****************+Idris' Internals+*****************++Note: this is still a fairly raw set of notes taken by David+Christiansen at Edwin's presentation at the 2013 Idris Developers+Meeting. They're in the process of turning into a useful guide - feel+free to contribute.++This document assumes that you are already familiar with Idris. It is+intended for those who want to work on the internals.++People looking to develop new back ends may want to look at [[Idris back+end IRs\|Idris-back-end-IRs]]++Core/TT.hs+==========++Idris is compiled to a simple, explicit core language. This core+language is called TT because it looks a bit like a Π. It's a minimal+language, with a locally nameless representation. That is, local+variables are represented with de Bruijn indices and globally-defined+constants are represented with names.++The ``TT`` datatype uses a trick that is common in the Idris code: it is+polymorphic over the type of names stored in it, and it derives+``Functor``. This allows ``fmap`` to be used as a general-purpose+traversal.++There is a general construction for binders, used for λ, Π, and+let-bindings. These are distinguished using a ``BinderType``.++During compilation, some terms (especially types) will be erased. This+is represented using the ``Erased`` constructor of ``TT``. A handy trick+when generating TT terms is to insert ``Erased`` where a term is+uniquely determined, as the typechecker will fill it out.++The constructor ``Proj`` is a result of the optimizer. It is used to+extract a specific constructor argument, in a more economical way than+defining a new pattern-matching operation.++The datatype ``Raw`` represents terms that have not yet been+typechecked. The typechecker converts a ``Raw`` to a ``TT`` if it can.++Core/CaseTree.hs+================++Case trees are used to represent top-level pattern-matching definitions+in the TT language.++Just as with the ``TT`` datatype, the ``deriving Functor`` trick is used+with ``SC`` and ``CaseAlt`` to get GHC to generate a function for+mapping over contained terms.++Constructor cases (``ConCase`` in ``CaseAlt``) refer to numbered+constructors. Every constructor is numbered 0,1,2,…. At this stage in+the compiler, the tags are datatype-local. After defunctionalization,+however, they are made globally unique.++The ``n+1`` patterns (``SucCase``) and hacky-seeming things are to make+code fast -- please ask before "cleaning up" the representation.++Core/Evaluate.hs+================++This module contains the main evaluator for Idris. The evaluator is used+both at the REPL and during type checking, where normalised terms need+to be compared for equality.++A key datatype in the evaluator is a *context*. Contexts are mappings+from global names to their values, but they are organized to make+type-directed disambiguation quick. In particular, the main part of a+name that a user might type is used as the key, and its values are maps+from namespaces to actual values.++The datatype ``Def`` represents a definition in the global context. All+global names map to this structure.++``Type`` and ``Term`` are both synonyms for ``TT``.++Datatypes are represented by a ``TyDecl`` with the appropriate+``NameType``. A ``Function`` is a global constant term with an annotated+type, ``Operator`` represents primitives implemented in Haskell, and+``CaseOp`` represents ordinary pattern-matching definitions. ``CaseOp``+has four versions for different purposes, and all are saved because+that's easiest.++``CaseInfo``: the ``tc_dictionary`` is because it's a type class+dictionary which makes totality checking easier.++The ``normalise*`` functions give different behaviors - but+``normalise`` is the most common.++``normaliseC`` - "resolved" means with names converted to de Bruijn+indices as appropriate.++``normaliseAll`` - reduce everything, even if it's non-total++``normaliseTrace`` - special-purpose for debugging++``simplify`` - reduce the things that are small - the list argument is+the things to not reduce.++Core/Typecheck.hs+=================++Standard stuff. Hopefully no changes are necessary.++Core/Elaborate.hs+=================++Idris definitions are elaborated one by one and turned into the+corresponding TT. This is done with a tactic language as an EDSL in the+Elab monad (or Elab' when there's a custom state).++Lots of plumbing for errors.++All elaboration is relative to a global context.++The string in the pair returned by elaborate is log information.++See JFP paper, but the names don't necessarily map to each other. The+paper is the "idealized version" without logging, additional state, etc.++All the tactics take Raws, typechecking happens there.++claim (x : t) assumes a new x : t.++PLEASE TIDY THINGS UP!++proofSearch flag to try' is whether the failure came from a human (so+fail) or from a machine (so continue)++Idris-level syntax for providing alternatives explicitly: (\| x, y, z+\|) try x, y, z in order, and take the first that succeeds.++Core/ProofState.hs+==================++Core/Unify.hs+=============++Deals with unification. Unification can reply with: - this works - this+can never work - this will work if these other unification problems work+out (eg unifying f x with 1)++match\_unify: same thing as unification except it's just matching name+against name, term against term. x + y matches to 0 + y with x = 0. Used+for <== syntax as well as type class resolution.++Idris/AbsSyntaxTree.hs+======================++PTerm is the datatype of Idris syntax. P is for Program. Each PTerm+turns into a TT term by applying a series of tactics.++IState is the major interpreter state. The global context is the+tt\_ctxt field.++Ctxt maps possibly ambiguous names to their referents.++Idris/ElabDecls.hs+==================++This is where the actual elaboration from PTerm to TT happens.++Idris/ElabTerm.hs+=================++build is the function that creates a Raw. All the "junk" is to deal with+things like metavars and so forth. It has to remember what names are+still to be defined, and it doesn't yet know the type (filled in by+unificaiton later). Also case expressions have to turn into top-level+functions.++resolveTC is type class resolution.
+ docs/reference/language-extensions.rst view
@@ -0,0 +1,36 @@+*******************+Language Extensions+*******************++++Type Providers+===============++Idris type providers are a way to get the type system to reflect+observations about the world outside of Idris. Similarly to `F# type+providers <http://msdn.microsoft.com/en-us/library/vstudio/hh156509.aspx>`__,+they cause effectful computations to run during type checking, returning+information that the type checker can use when checking the rest of the+program. While F# type providers are based on code generation, Idris+type providers use only the ordinary execution semantics of Idris to+generate the information.++A type provider is simply a term of type ``IO (Provider t)``, where+``Provider`` is a data type with constructors for a successful result+and an error. The type ``t`` can be either ``Type`` (the type of types)+or a concrete type. Then, a type provider ``p`` is invoked using the+syntax ``%provide (x : t) with p``. When the type checker encounters+this line, the IO action ``p`` is executed. Then, the resulting term is+extracted from the IO monad. If it is ``Provide y`` for some ``y : t``,+then ``x`` is bound to ``y`` for the remainder of typechecking and in+the compiled code. If execution fails, a generic error is reported and+type checking terminates. If the resulting term is ``Error e`` for some+string ``e``, then type checking fails and the error ``e`` is reported+to the user.++Example Idris type providers can be seen at `this+repository <https://github.com/david-christiansen/idris-type-providers>`__.+More detailed descriptions are available in David Christiansen's `WGP+'13 paper <http://dx.doi.org/10.1145/2502488.2502495>`__ and `M.Sc.+thesis <http://itu.dk/people/drc/david-christiansen-thesis.pdf>`__.
+ docs/reference/language-features.rst view
@@ -0,0 +1,54 @@+**********************+Core Language Features+**********************+++-  Full-spectrum dependent types+-  Strict evaluation (plus ``Lazy : Type -> Type`` type constructor for+   explicit laziness)+-  Lambda, Pi (forall), Let bindings+-  Pattern matching definitions+-  Export modifiers ``public``, ``abstract``, ``private``+-  Function options ``partial``, ``total``+-  ``where`` clauses+-  "magic with"+-  Implicit arguments (in top level types)+-  "Bound" implicit arguments ``{n : Nat} -> {a : Type} -> Vect n a``+-  "Unbound" implicit arguments --- ``Vect n a`` is equivalent to the+   above in a type, ``n`` and ``a`` are implicitly bound. This applies+   to names beginning with a lower case letter in an argument position.+-  'Tactic' implicit arguments, which are solved by running a tactic+   script or giving a default argument, rather than by unification.+-  Unit type ``()``, empty type ``Void``+-  Tuples (desugaring to nested pairs)+-  Dependent pair syntax ``(x : T ** P x)`` (there exists an ``x`` of+   type ``T`` such that ``P x``)+-  Inline ``case`` expressions+-  Heterogeneous equality+-  ``do`` notation+-  Idiom brackets+-  Interfaces (like type classes), supporting default methods and dependencies between+   methods+-  ``rewrite`` prf ``in`` expr+-  Metavariables+-  Inline proof/tactic scripts+-  Implicit coercion+-  ``codata``+-  Also ``Inf : Type -> Type`` type constructor for mixed data/codata.+   In fact ``codata`` is implemented by putting recursive arguments under+   ``Inf``.+-  ``syntax`` rules for defining pattern and term syntactic sugar+-  these are used in the standard library to define+   ``if ... then ... else`` expressions and an Agda-style preorder+   reasoning syntax.+-  `Uniqueness+   typing <https://github.com/idris-lang/Idris-dev/wiki/Uniqueness-Types>`__+   using the ``UniqueType`` universe.+-  `Partial+   evaluation <https://github.com/idris-lang/Idris-dev/wiki/Static-Arguments-and-Partial-Evaluation>`__+   by ``%static`` argument annotations.+-  Error message reflection+-  Eliminators+-  Label types ``'name``+-  ``%logging n``+-  ``%unifyLog``
+ docs/reference/misc.rst view
@@ -0,0 +1,335 @@+**************+Miscellaneous+**************++Things we have yet to classify, or are two small to justify their own page.+++The Unifier Log+===============++If you're having a hard time debugging why the unifier won't accept+something (often while debugging the compiler itself), try applying the+special operator ``%unifyLog`` to the expression in question. This will+cause the type checker to spit out all sorts of informative messages.+++Namespaces and type-directed disambiguation+===========================================++Names can be defined in separate namespaces, and disambiguated by type.+An expression ``with NAME EXPR`` will privilege the namespace ``NAME``+in the expression ``EXPR``. For example:++::++    Idris> with List [[1,2],[3,4],[5,6]]+    [[1, 2], [3, 4], [5, 6]] : List (List Integer)++    Idris> with Vect [[1,2],[3,4],[5,6]]+    [[1, 2], [3, 4], [5, 6]] : Vect 3 (Vect 2 Integer)++    Idris> [[1,2],[3,4],[5,6]]+    Can't disambiguate name: Prelude.List.::, Prelude.Stream.::, Prelude.Vect.::+++Alternatives+============++The syntax ``(| option1, option2, option3, ... |)`` type checks each+of the options in turn until one of them works. This is used, for+example, when translating integer literals.++::++    Idris> the Nat (| "foo", Z, (-3) |)+    0 : Nat+++This can also be used to give simple automated proofs, for example: trying+some constructors of proofs.++::++    syntax Trivial = (| oh, refl |)+++Totality checking assertions+============================++All definitions are checked for *coverage* (i.e. all well-typed+applications are handled) and either for *termination* (i.e. all+well-typed applications will eventually produce an answer) or, if+returning codata, for productivity (in practice, all recursive calls are+constructor guarded).++Obviously, termination checking is undecidable. In practice, the+termination checker looks for *size change* - every cycle of recursive+calls must have a decreasing argument, such as a recursive argument of a+strictly positive data type.++There are two built-in functions which can be used to give the totality+checker a hint:++-  ``assert_total x`` asserts that the expression ``x`` is terminating+   and covering, even if the totality checker cannot tell. This can be+   used for example if ``x`` uses a function which does not cover all+   inputs, but the caller knows that the specific input is covered.+-  ``assert_smaller p x`` asserts that the expression ``x`` is+   structurally smaller than the pattern ``p``.++For example, the following function is not checked as total:++::++    qsort : Ord a => List a -> List a+    qsort [] = []+    qsort (x :: xs) = qsort (filter (<= x) xs) ++ (x :: qsort (filter (>= x) xs)))++This is because the checker cannot tell that ``filter`` will always+produce a value smaller than the pattern ``x :: xs`` for the recursive+call to ``qsort``. We can assert that this will always be true as+follows:++::++    total+    qsort : Ord a => List a -> List a+    qsort [] = []+    qsort (x :: xs) = qsort (assert_smaller (x :: xs) (filter (<= x) xs)) +++                      (x :: qsort (assert_smaller (x :: xs) (filter (>= x) xs))))+++C heap+======++Idris has two heaps where objects can be allocated:+++--------------------------------------+---------------------------------------++| FP heap                              | C heap                                |++======================================+=======================================++| Cheney-collected                     | Mark-and-sweep-collected              |++--------------------------------------+---------------------------------------++| Garbage collections touches only     | Garbage collection has to traverse    |+| live objects.                        | all registered items.                 |++--------------------------------------+---------------------------------------++| Ideal for FP-style rapid allocation  | Ideal for C-style allocation of a few |+| of lots of small short-lived pieces  | big buffers.                          |+| of memory, such as data constructors.|                                       |++--------------------------------------+---------------------------------------++| Finalizers are impossible to support | Items have finalizers that are called |+| reasonably.                          | on deallocation.                      |++--------------------------------------+---------------------------------------++| Data is copied all the time (when    | Copying does not happen.              |+| collecting garbage, modifying data,  |                                       |+| registering managed pointers, etc.)  |                                       |++--------------------------------------+---------------------------------------++| Contains objects of various types.   | Contains C heap items: ``(void *)``   |+|                                      | pointers with finalizers. A finalizer |+|                                      | is a routine that deallocates the     |+|                                      | resources associated with the item.   |++--------------------------------------+---------------------------------------++| Fixed set of object types.           | The data pointer may point            |+|                                      | to anything, as long as the finalizer |+|                                      | cleans up correctly.                  |++--------------------------------------+---------------------------------------++| Not suitable for C resources and     | Suitable for C resources and arbitrary|+| arbitrary pointers.                  | pointers.                             |++--------------------------------------+---------------------------------------++| Values form a compact memory block.  | Items are kept in a linked list.      |++--------------------------------------+---------------------------------------++| Any Idris value, most notably        | Items represented by the              |+| ``ManagedPtr``.                      | Idris type ``CData``.                 |++--------------------------------------+---------------------------------------++| Data of ``ManagedPtr`` allocated     | Data allocated in C, pointer copied   |+| in C, buffer then copied into the FP | into the C heap.                      |+| heap.                                |                                       |++--------------------------------------+---------------------------------------++| Allocation and reallocation not      | Allocated and reallocate freely in C, |+| possible from C code (without having | registering the allocated items       |+| a reference to the VM). Everything   | in the FFI.                           |+| is copied instead.                   |                                       |++--------------------------------------+---------------------------------------+++The FP heap is the primary heap. It may contain values of type ``CData``,+which are references to items in the C heap. A C heap item contains+a ``(void *)`` pointer and the corresponding finalizer. Once a C heap item+is no longer referenced from the FP heap, it is marked as unused and+the next GC sweep will call its finalizer and deallocate it.++There is no Idris interface for ``CData`` other than its type and FFI.++Usage from C code+-----------------++* Although not enforced in code, ``CData`` is meant to be opaque+  and non-RTS code (such as libraries or C bindings) should+  access only its ``(void *)`` field called ``data``.++* Feel free to mutate both the pointer ``data`` (eg. after calling ``realloc``)+  and the memory it points to. However, keep in mind+  that this must not break Idris's referential transparency.++* **WARNING!** If you call ``cdata_allocate`` or ``cdata_manage``,+  the resulting ``CData`` object *must* be returned from your+  FFI function so that it is inserted in the C heap by the RTS.+  Otherwise the memory will be leaked.++.. code:: idris++    some_allocating_fun : Int -> IO CData+    some_allocating_fun i = foreign FFI_C "some_allocating_fun" (Int -> IO CData) i++    other_fun : CData -> Int -> IO Int+    other_fun cd i = foreign FFI_C "other_fun" (CData -> Int -> IO Int) cd i++.. code:: cpp++    #include "idris_rts.h"++    static void finalizer(void * data)+    {+        MyStruct * ptr = (MyStruct *) data;+        free_something(ptr->something);+        free(ptr);+    }++    CData some_allocating_fun(int arg)+    {+        void * data = (void *) malloc(...);+        // ...+        return cdata_manage(data, finalizer);+    }++    int other_fun(CData cd, int arg)+    {+        int result = foo(cd->data);+        return result;+    }++Preorder reasoning+==================++This syntax is defined in the module ``Syntax.PreorderReasoning`` in the+``base`` package. It provides a syntax for composing proofs of+reflexive-transitive relations, using overloadable functions called+``step`` and ``qed``. This module also defines ``step`` and ``qed``+functions allowing the syntax to be used for demonstrating equality.+Here is an example:++.. code:: idris++    import Syntax.PreorderReasoning+    multThree : (a, b, c : Nat) -> a * b * c = c * a * b+    multThree a b c =+      (a * b * c) ={ sym (multAssociative a b c) }=+      (a * (b * c)) ={ cong (multCommutative b c) }=+      (a * (c * b)) ={ multAssociative a c b }=+      (a * c * b) ={ cong {f = (* b)} (multCommutative a c) }=+      (c * a * b) QED++Note that the parentheses are required -- only a simple expression can+be on the left of ``={ }=`` or ``QED``. Also, when using preorder+reasoning syntax to prove things about equality, remember that you can+only relate the entire expression, not subexpressions. This might+occasionally require the use of ``cong``.++Finally, although equality is the most obvious application of preorder+reasoning, it can be used for any reflexive-transitive relation.+Something like ``step1 ={ just1 }= step2 ={ just2 }= end QED`` is+translated to ``(step step1 just1 (step step2 just2 (qed end)))``,+selecting the appropriate definitions of ``step`` and ``qed`` through+the normal disambiguation process. The standard library, for example,+also contains an implementation of preorder reasoning on isomorphisms.+++Pattern matching on Implicit Arguments+======================================++Pattern matching is only allowed on implicit arguments when they are+referred by name, e.g.++.. code:: idris++    foo : {n : Nat} -> Nat+    foo {n = Z} = Z+    foo {n = S k} = k++or++.. code:: idris++    foo : {n : Nat} -> Nat+    foo {n = n} = n++The latter could be shortened to the following:++.. code:: idris++    foo : {n : Nat} -> Nat+    foo {n} = n++That is, ``{x}`` behaves like ``{x=x}``.+++Existence of an implementation+========================++In order to show that an implementation of some interface is defined for some+type, one could use the ``%implementation`` keyword:++.. code:: idris++    foo : Num Nat+    foo = %implementation++'match' application+===================++``ty <== name`` applies the function ``name`` in such a way that it has+the type ``ty``, by matching ``ty`` against the function's type. This+can be used in proofs, for example:++::++    plus_comm : (n : Nat) -> (m : Nat) -> (n + m = m + n)+    -- Base case+    (Z + m = m + Z) <== plus_comm =+        rewrite ((m + Z = m) <== plusZeroRightNeutral) ==>+                (Z + m = m) in refl++    -- Step case+    (S k + m = m + S k) <== plus_comm =+        rewrite ((k + m = m + k) <== plus_comm) in+        rewrite ((S (m + k) = m + S k) <== plusSuccRightSucc) in+            refl++Reflection+==========++Including ``%reflection`` functions and ``quoteGoal x by fn in t``,+which applies ``fn`` to the expected type of the current expression, and+puts the result in ``x`` which is in scope when elaborating ``t``.++Bash Completion+================++Use of ``optparse-applicative`` allows Idris to support Bash+completion.  You can obtain the completion script for Idris using the+following command::++   idris --bash-completion-script `which idris`+++To enable completion for the lifetime of your current session, run the+following command::++   source <(idris --bash-completion-script `which idris`)+++To enable completion permenatly you must either:++* Modify your bash init script with the above command.++* Add the completion script to the appropriate ``bash_completion.d/``+  folder on your machine.
+ docs/reference/packages.rst view
@@ -0,0 +1,138 @@+.. _ref-sect-packages:++********+Packages+********++Idris includes a simple system for building packages from a+package description file. These files can be used with the Idris+compiler to manage the development process of your Idris+programmes and packages.++Package Descriptions+====================++A package description includes the following:+++ A header, consisting of the keyword package followed by the package+  name. Package names can be any valid Idris identifier. The iPKG+  format also takes a quoted version that accepts any valid filename.++ Fields describing package contents, ``<field> = <value>``++At least one field must be the modules field, where the value is a+comma separated list of modules.  For example, a library test which+has two modules ``foo.idr`` and ``bar.idr`` as source files would be+written as follows::++    package foo++    modules = foo, bar++Other examples of package files can be found in the ``libs`` directory+of the main Idris repository, and in `third-party libraries <https://github.com/idris-lang/Idris-dev/wiki/Libraries>`_.++Metadata+--------++From Idris `v0.12` the `iPKG` format supports additional metadata+associated with the package.+The added fields are:+++ ``brief = "<text>"``, a string literal containing a brief description+  of the package.+++ ``version = <text>``, a version string to associate with the package.+++ ``readme = <file>``, location of the README file.+++ ``license = <text>``, a string description of the licensing+  information.+++ ``author = <text>``, the author information.+++ ``maintainer = <text>``, Maintainer information.+++ ``homepage = <url>``, the website associated with the package.+++ ``sourceloc = <url>``, the location of the DVCS where the source+  can be found.+++ ``bugtracker = <url>``, the location of the project's bug tracker.+++Common Fields+-------------++Other common fields which may be present in an ``ipkg`` file are:+++ ``sourcedir = <dir>``, which takes the directory (relative to the+  current directory) which contains the source. Default is the current+  directory.+++ ``executable = <output>``, which takes the name of the executable+  file to generate. Executable names can be any valid Idris+  identifier. the iPKG format also takes a quoted version that accepts+  any valid filename.+++ ``main = <module>``, which takes the name of the main module, and+  must be present if the executable field is present.+++ ``opts = "<idris options>"``, which allows options to be passed to+  Idris.+++ ``pkgs = <pkg name> (',' <pkg name>)+``, a comma separated list of+  package names that the Idris package requires.++Binding to C+------------++In more advanced cases, particularly to support creating bindings to+external ``C`` libraries, the following options are available:+++ ``makefile = <file>``, which specifies a ``Makefile``, to be built+  before the Idris modules, for example to support linking with a+  ``C`` library.+++ ``libs = <libs>``, which takes a comma separated list of libraries+  which must be present for the package to be usable.+++ ``objs = <objs>``, which takes a comma separated list of additional+  files to be installed (object files, headers), perhaps generated +  by the ``Makefile``.++Testing+--------++For testing Idris packages there is a rudimentary testing harness, run in the ``IO`` context.+The ``iPKG`` file is used to specify the functions used for testing.+The following option is available:+++ ``tests = <test functions>``, which takes the qualified names of all test functions to be run.++.. IMPORTANT::+  The modules containing the test functions must also be added to the list of modules.++Using Package files+===================++Given an Idris package file ``text.ipkg`` it can be used with the Idris compiler as follows:+++ ``idris --build test.ipkg`` will build all modules in the package+++ ``idris --install test.ipkg`` will install the package, making it+  accessible by other Idris libraries and programs.+++ ``idris --clean test.ipkg`` will delete all intermediate code and+  executable files generated when building.+++ ``idris --mkdoc test.ipkg`` will build HTML documentation for your package in the folder ``test_doc`` in your project's root directory.+++ ``idris --checkpkg test.ipkg`` will type check all modules in the package only. This differs from build that type checks **and** generates code.+++ ``idris --testpkg test.ipkg`` will compile and run any embedded tests you have specified in the ``tests`` parameter.++Once the test package has been installed, the command line option+``--package test`` makes it accessible (abbreviated to ``-p test``).+For example::++    idris -p test Main.idr
+ docs/reference/partial-evaluation.rst view
@@ -0,0 +1,305 @@+****************************************+Static Arguments and Partial Evaluation+****************************************++As of version 0.9.15, Idris has support for *partial evaluation* of+statically known arguments. This involves creating specialised versions+of functions with arguments annotated as ``[static]``.++(This is an implementation of the partial evaluator described in `this+ICFP 2010+paper <http://eb.host.cs.st-andrews.ac.uk/writings/icfp10.pdf>`__.+Please refer to this for more precise definitions of what follows.)++Partial evaluation is switched on by default. It can be disabled with+the ``--no-partial-eval`` flag.++Introductory Example+--------------------++Consider the power function over natural numbers, defined as follows+(we'll call it ``my_pow`` since ``pow`` already exists in the Prelude):++::++    my_pow : Nat -> Nat -> Nat+    my_pow x Z = 1+    my_pow x (S k) = mult x (my_pow x k)++This is implemented by recursion on the second argument, and we can+evaluate the definition further if the second argument is known, even if+the first isn't. For example, we can build a function at the REPL to+cube a number as follows:++::++    *pow> \x => my_pow x 3+    \x => mult x (mult x (mult x 1)) : Nat -> Nat+    *pow> it 3+    27 : Nat++Note that in the resulting function the recursion has been eliminated,+since ``my_pow`` is implemented by recursion on the known argument. We+have no such luck if the first argument is known and the second isn't:++::++    *pow> \x => my_pow 2 x+    \x => my_pow 2 x : Nat -> Nat++Now, consider the following definition which calculates x^2 + 1:++::++    powFn : Nat -> Nat+    powFn x = plus (my_pow x (S (S Z))) (S Z)++Since the second argument to ``my_pow`` here is statically known, it+seems a shame to have to make the recursive calls every time. However,+Idris will not in general inline recursive definitions, in particular+since they may diverge or duplicate work without some deeper analysis.++We can, however, give Idris some hints that here we really would like to+create a specialised version of ``my_pow``.++Automatic specialisation of ``pow``+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++The trick is to mark the statically known arguments with the+``[static]`` flag:++::++    my_pow : Nat -> [static] Nat -> Nat+    my_pow k Z = 1+    my_pow k (S j) = mult k (my_pow k j)++When an argument is annotated in this way, Idris will try to create a+specialised version whenever it accounts a call with a concrete value+(i.e. a constant, constructor form, or globally defined function) in a+``[static]`` position. If ``my_pow`` is defined this way, and ``powFn``+defined as above, we can see the effect by typing ``:printdef powFn`` at+the REPL:++::++    *pow> :printdef powFn+    powFn : Nat -> Nat+    powFn x = plus (PE_my_pow_3f3e5ad8 x) 1++What is this mysterious ``PE_my_pow_3f3e5ad8``? It's a specialised power+function where the statically known argument has been specialised away.+The name is generated from a hash of the specialised arguments, and we+can see its definition with ``:printdef`` too:++::++    *petest> :printdef PE_my_pow_3f3e5ad8+    PE_my_pow_3f3e5ad8 : Nat -> Nat+    PE_my_pow_3f3e5ad8 (0arg) = mult (0arg) (mult (0arg) (PE_fromInteger_7ba9767f 1))++The ``(0arg)`` is an internal argument name (programmers can't give+variable names beginning with a digit after all). Notice also that there+is a specialised version of ``fromInteger`` for ``Nat``\ s, since type+class dictionaries are themselves a particularly common case of+statically known arguments!++Specialising Type Classes+-------------------------++Type class dictionaries are very often statically known, so Idris+automatically marks any type class constraint as ``[static]`` and builds+specialised versions of top level functions where the class is+instantiated. For example, given:++::++    calc : Int -> Int+    calc x = (x * x) + x++If we print this definition, we'll see a specialised version of ``+`` is+used:++::++    *petest> :printdef calc+    calc : Int -> Int+    calc x = PE_+_954510b4 (PE_*_954510b4 x x) x++More interestingly, consider ``vadd`` which adds corresponding elements+in a vector of anything numeric:++::++    vadd : Num a => Vect n a -> Vect n a -> Vect n a+    vadd [] [] = []+    vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys++If we use this on something concrete as follows...++::++    test : List Int -> List Int+    test xs = let xs' = fromList xs in+                  toList $ vadd xs' xs'++...then in fact, we get a specialised version of ``vadd`` in the+definition of ``test``, and indeed the specialised version of+``toList``:++::++    test : List Int -> List Int+    test xs = let xs' = fromList xs+              in PE_toList_888ae67 (PE_vadd_33f98d3d xs' xs')++Here's the specialised version of ``vadd``:++::++    PE_vadd_33f98d3d : Vect n Int -> Vect n Int -> Vect n Int+    PE_vadd_33f98d3d [] [] = []+    PE_vadd_33f98d3d (x :: xs) (y :: ys) = ((PE_+_954510b4 x y) ::+                                           (PE_vadd_33f98d3d xs ys))++Note that the recursive structure has been preserved, and the recursive+call to ``vadd`` has been replaced with a recursive call to the+specialised version. We've also got the same specialised version of+``+`` that we had above in ``calc``.++Specialising Higher Order Functions+-----------------------------------++Another case where partial evaluation can be useful is in automatically+making specialised versions of higher order functions. Unlike type class+dictionaries, this is not done automatically, but we might consider+writing ``map`` as follows:++::++    my_map : [static] (a -> b) -> List a -> List b+    my_map f [] = []+    my_map f (x :: xs) = f x :: my_map f xs++Then using ``my_map`` will yield specialised versions, for example to+double every value in a list of ``Int``\ s we could write:++::++    doubleAll : List Int -> List Int+    doubleAll xs = my_map (*2) xs++This would yield a specialised version of ``my_map``, used in+``doubleAll`` as follows:++::++    doubleAll : List Int -> List Int+    doubleAll xs = PE_my_map_1f8225c4 xs++    PE_my_map_1f8225c4 : List Int -> List Int+    PE_my_map_1f8225c4 [] = []+    PE_my_map_1f8225c4 (x :: xs) = ((PE_*_954510b4 x 2) :: (PE_my_map_1f8225c4 xs))++Specialising Interpreters+-------------------------++A particularly useful situation where partial evaluation becomes+effective is in defining an interpreter for a well-typed expression+language, defined as follows (see the `Idris tutorial, section+4 <http://eb.host.cs.st-andrews.ac.uk/writings/idris-tutorial.pdf>`__+for more details on how this works):++::++    data Expr : Vect n Ty -> Ty -> Type where+         Var : HasType i gamma t -> Expr gamma t+         Val : (x : Int) -> Expr gamma TyInt+         Lam : Expr (a :: gamma) t -> Expr gamma (TyFun a t)+         App : Lazy (Expr gamma (TyFun a t)) -> Expr gamma a -> Expr gamma t+         Op  : (interpTy a -> interpTy b -> interpTy c) -> Expr gamma a -> Expr gamma+               Expr gamma c+         If  : Expr gamma TyBool -> Expr gamma a -> Expr gamma a -> Expr gamma a++    dsl expr+        lambda = Lam+        variable = Var+        index_first = stop+        index_next = pop++We can write a couple of test functions in this language as follows,+using the ``dsl`` notation to overload lambdas; first a function which+multiplies two inputs:++::++    eMult : Expr gamma (TyFun TyInt (TyFun TyInt TyInt))+    eMult = expr (\x, y => Op (*) x y)++Then, a function which calculates the factorial of its input:++::++    eFac : Expr gamma (TyFun TyInt TyInt)+    eFac = expr (\x => If (Op (==) x (Val 0))+                (Val 1)+                (App (App eMult (App eFac (Op (-) x (Val 1)))) x))++The interpreter's type is written as follows, marking the expression to+be evaluated as ``[static]``:++::++    interp : (env : Env gamma) -> [static] (e : Expr gamma t) -> interpTy t++This means that if we write an Idris program to calculate a factorial by+calling ``interp`` on ``eFac``, the resulting definition will be+specialised, partially evaluating away the interpreter:++::++    runFac : Int -> Int+    runFac x = interp [] eFac x++We can see that the call to ``interp`` has been partially evaluated away+as follows:++::++    *interp> :printdef runFac+    runFac : Int -> Int+    runFac x = PE_interp_ed1429e [] x++If we look at ``PE_interp_ed1429e`` we'll see that it follows exactly+the structur of ``eFac``, with the interpreter evaluated away:++::++    *interp> :printdef PE_interp_ed1429e+    PE_interp_ed1429e : Env gamma -> Int -> Int+    PE_interp_ed1429e (3arg) = \x =>+                                 boolElim (x == 0)+                                          (Delay 1)+                                          (Delay (PE_interp_b5c2d0ff (x :: (3arg))+                                                                     (PE_interp_ed1429e (x :: (3arg)) (x - 1)) x))+++For the sake of readability, I have simplified this slightly: what you+will really see also includes specialised versions of ``==``, ``-`` and+``fromInteger``. Note that ``PE_interp_ed1429e``, which represents+``eFac`` has become a recursive function following the structure of+``eFac``. There is also a call to ``PE_interp_b5c2d0ff`` which is a+specialised interpeter for ``eMult``.++These definitions arise because the partial evaluator will only+specialise a definition by a specific concrete argument once, then it is+cached for future use. So any future applications of ``interp`` on+``eFac`` will also be translated to ``PE_interp_ed1429e``.++The specialised version of ``eMult``, without any simplification for+readability, is:++::++    PE_interp_b5c2d0ff : Env gamma -> Int -> Int -> Int+    PE_interp_b5c2d0ff (3arg) = \x => \x1 => PE_*_954510b4 x x1
+ docs/reference/repl.rst view
@@ -0,0 +1,546 @@+.. _sect-repl:++**************+The Idris REPL+**************++Idris comes with a ``REPL``.++Evaluation+==========++Being a fully dependently typed language, Idris has two phases where it+evaluates things, compile-time and run-time. At compile-time it will only+evaluate things which it knows to be total (i.e. terminating and covering all+possible inputs) in order to keep type checking decidable. The compile-time+evaluator is part of the Idris kernel, and is implemented in Haskell using a+HOAS (higher order abstract syntax) style representation of values. Since+everything is known to have a normal form here, the evaluation strategy doesn't+actually matter because either way it will get the same answer, and in practice+it will do whatever the Haskell run-time system chooses to do.++The REPL, for convenience, uses the compile-time notion of evaluation. As well+as being easier to implement (because we have the evaluator available) this can+be very useful to show how terms evaluate in the type checker. So you can see+the difference between:++.. code-block:: idris++    Idris> \n, m => (S n) + m+    \n => \m => S (plus n m) : Nat -> Nat -> Nat++    Idris> \n, m => n + (S m)+    \n => \m => plus n (S m) : Nat -> Nat -> Nat++Customisation+=============++Idris supports initialisation scripts.++Initialisation scripts+~~~~~~~~~~~~~~~~~~~~~~++When the Idris REPL starts up, it will attempt to open the file+repl/init in Idris's application data directory. The application data+directory is the result of the Haskell function call+``getAppUserDataDirectory "idris"``, which on most Unix-like systems+will return $HOME/.idris and on various versions of Windows will return+paths such as ``C:/Documents And Settings/user/Application Data/appName``.++The file repl/init is a newline-separate list of REPL commands. Not all+commands are supported in initialisation scripts — only the subset that+will not interfere with the normal operation of the REPL. In particular,+setting colours, display options such as showing implicits, and log+levels are supported.++Example initialisation script+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+::++    :colour prompt white italic bold+    :colour implicit magenta italic++++The ``REPL`` Commands+=====================++The current set of supported commands are:+++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|Command         | Arguments                    | Purpose                                                                                                  |++================+==============================+==========================================================================================================++|<expr>          |                              | Evaluate an expression                                                                                   |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:t :type        | <expr>                       | Check the type of an expression                                                                          |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:core           | <expr>                       | View the core language representation of a term                                                          |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:miss :missing  | <name>                       | Show missing clauses                                                                                     |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:doc            | <name>                       | Show internal documentation                                                                              |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:mkdoc          | <namespace>                  | Generate IdrisDoc for namespace(s) and dependencies                                                      |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:apropos        | [<package list>] <name>      | Search names, types, and documentation                                                                   |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:s :search      | [<package list>] <expr>      | Search for values by type                                                                                |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:wc :whocalls   | <name>                       | List the callers of some name                                                                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:cw :callswho   | <name>                       | List the callees of some name                                                                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:browse         | <namespace>                  | List the contents of some namespace                                                                      |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:total          | <name>                       | Check the totality of a name                                                                             |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:r :reload      |                              | Reload current file                                                                                      |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:l :load        | <filename>                   | Load a new file                                                                                          |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:cd             | <filename>                   | Change working directory                                                                                 |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:module         | <module>                     | Import an extra module                                                                                   |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:e :edit        |                              | Edit current file using $EDITOR or $VISUAL                                                               |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:m :metavars    |                              | Show remaining proof obligations (holes)                                                                 |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:p :prove       | <hole>                       | Prove a hole                                                                                             |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:a :addproof    | <name>                       | Add proof to source file                                                                                 |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:rmproof        | <name>                       | Remove proof from proof stack                                                                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:showproof      | <name>                       | Show proof                                                                                               |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:proofs         |                              | Show available proofs                                                                                    |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:x              | <expr>                       | Execute IO actions resulting from an expression using the interpreter                                    |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:c :compile     | <filename>                   | Compile to an executable [codegen] <filename>                                                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:exec :execute  | [<expr>]                     | Compile to an executable and run                                                                         |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:dynamic        | <filename>                   | Dynamically load a C library (similar to %dynamic)                                                       |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:dynamic        |                              | List dynamically loaded C libraries                                                                      |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:? :h :help     |                              | Display this help text                                                                                   |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:set            | <option>                     | Set an option (errorcontext, showimplicits, originalerrors, autosolve, nobanner, warnreach, evaltypes,   |+|                |                              | desugarnats)                                                                                             |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:unset          | <option>                     | Unset an option                                                                                          |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:color :colour  | <option>                     | Turn REPL colours on or off; set a specific colour                                                       |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:consolewidth   | auto|infinite|<number>       | Set the width of the console                                                                             |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:printerdepth   | <number-or-blank>            | Set the maximum pretty-printing depth, or infinite if nothing specified                                  |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:q :quit        |                              | Exit the Idris system                                                                                    |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:w :warranty    |                              | Displays warranty information                                                                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:let            | (<top-level-declaration>)... | Evaluate a declaration, such as a function definition, instance implementation, or fixity declaration    |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:unlet :undefine|(<name>)...                   | Remove the listed repl definitions, or all repl definitions if no names given                            |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:printdef       | <name>                       | Show the definition of a function                                                                        |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++|:pp :pprint     | <option> <number> <name>     | Pretty prints an Idris function in either LaTeX or HTML and for a specified width.                       |++----------------+------------------------------+----------------------------------------------------------------------------------------------------------++++Using the REPL+==============+++Getting help+~~~~~~~~~~~~++The command ``:help`` (or ``:h`` or ``:?``) prints a short summary of+the available commands.++Quitting Idris+~~~~~~~~~~~~~~++If you would like to leave Idris, simply use ``:q`` or ``:quit``.++Evaluating expressions+~~~~~~~~~~~~~~~~~~~~~~++To evaluate an expression, simply type it. If Idris is unable to infer+the type, it can be helpful to use the operator ``the`` to manually+provide one, as Idris's syntax does not allow for direct type+annotations. Examples of ``the`` include:++::++    Idris> the Nat 4+    4 : Nat+    Idris> the Int 4+    4 : Int+    Idris> the (List Nat) [1,2]+    [1,2] : List Nat+    Idris> the (Vect _ Nat) [1,2]+    [1,2] : Vect 2 Nat++This may not work in cases where the expression still involves ambiguous+names. The name can be disambiguated by using the ``with`` keyword:++::++    Idris> sum [1,2,3]+    When elaborating an application of function Prelude.Foldable.sum:+            Can't disambiguate name: Prelude.List.::,+                                     Prelude.Stream.::,+                                     Prelude.Vect.::+    Idris> with List sum [1,2,3]+    6 : Integer++Adding let bindings+~~~~~~~~~~~~~~~~~~~++To add a let binding to the REPL, use ``:let``. It's likely you'll also+need to provide a type annotation. ``:let`` also works for other+declarations as well, such as ``data``.++::++    Idris> :let x : String; x = "hello"+    Idris> x+    "hello" : String+    Idris> :let y = 10+    Idris> y+    10 : Integer+    Idris> :let data Foo : Type where Bar : Foo+    Idris> Bar+    Bar : Foo++Getting type information+~~~~~~~~~~~~~~~~~~~~~~~~++To ask Idris for the type of some expression, use the ``:t`` command.+Additionally, if used with an overloaded name, Idris will provide all+overloadings and their types. To ask for the type of an infix operator,+surround it in parentheses.++::++    Idris> :t "foo"+    "foo" : String+    Idris> :t plus+    Prelude.Nat.plus : Nat -> Nat -> Nat+    Idris> :t (++)+    Builtins.++ : String -> String -> String+    Prelude.List.++ : (List a) -> (List a) -> List a+    Prelude.Vect.++ : (Vect m a) -> (Vect n a) -> Vect (m + n) a+    Idris> :t plus 4+    plus (Builtins.fromInteger 4) : Nat -> Nat++You can also ask for basic information about interfaces with ``:doc``:++::++    Idris> :doc Monad+    Interface Monad++    Parameters:+        m++    Methods:+        (>>=) : Monad m => m a -> (a -> m b) -> m b++            infixl 5++    Instances:+        Monad id+        Monad PrimIO+        Monad IO+        Monad Maybe++    ...++Other documentation is also available from ``:doc``:++::++    Idris> :doc (+)+    Prelude.Interfaces.(+) : Num ty => ty -> ty -> ty++    infixl 8++    The function is Total++::++    Idris> :doc Vect+    Data type Prelude.Vect.Vect : Nat -> Type -> Type++    Arguments:+            Nat+            Type++    Constructors:++    Prelude.Vect.Nil : (a : Type) -> Vect 0 a+++    Prelude.Vect.:: : (a : Type) -> (n : Nat) -> a -> (Vect n a) -> Vect (S n) a++    infixr 7++    Arguments:+            a+            Vect n a++::++    Idris> :doc Monad+    Interface Monad++    Parameters:+        m++    Methods:+        (>>=) : Monad m => m a -> (a -> m b) -> m b+            Also called bind.+            infixl 5++            The function is Total+        join : Monad m => m (m a) -> m a+            Also called flatten or mu++            The function is Total+    Implementations:+        Monad (IO' ffi)+        Monad Stream+        Monad Provider+        Monad Elab+        Monad PrimIO+        Monad Maybe+        Monad (Either e)+        Monad List++Finding things+~~~~~~~~~~~~~~++The command ``:apropos`` searches names, types, and documentation for+some string, and prints the results. For example:++::++    Idris> :apropos eq+    eqPtr : Ptr -> Ptr -> IO Bool+++    eqSucc : (left : Nat) -> (right : Nat) -> (left = right) -> S left = S right+    S preserves equality++    lemma_both_neq : ((x = x') -> _|_) -> ((y = y') -> _|_) -> ((x, y) = (x', y')) -> _|_+++    lemma_fst_neq_snd_eq : ((x = x') -> _|_) -> (y = y') -> ((x, y) = (x', y)) -> _|_+++    lemma_snd_neq : (x = x) -> ((y = y') -> _|_) -> ((x, y) = (x, y')) -> _|_+++    lemma_x_eq_xs_neq : (x = y) -> ((xs = ys) -> _|_) -> (x :: xs = y :: ys) -> _|_+++    lemma_x_neq_xs_eq : ((x = y) -> _|_) -> (xs = ys) -> (x :: xs = y :: ys) -> _|_+++    lemma_x_neq_xs_neq : ((x = y) -> _|_) -> ((xs = ys) -> _|_) -> (x :: xs = y :: ys) -> _|_+++    prim__eqB16 : Bits16 -> Bits16 -> Int++    prim__eqB16x8 : Bits16x8 -> Bits16x8 -> Bits16x8++    prim__eqB32 : Bits32 -> Bits32 -> Int++    prim__eqB32x4 : Bits32x4 -> Bits32x4 -> Bits32x4++    prim__eqB64 : Bits64 -> Bits64 -> Int++    prim__eqB64x2 : Bits64x2 -> Bits64x2 -> Bits64x2++    prim__eqB8 : Bits8 -> Bits8 -> Int++    prim__eqB8x16 : Bits8x16 -> Bits8x16 -> Bits8x16++    prim__eqBigInt : Integer -> Integer -> Int++    prim__eqChar : Char -> Char -> Int++    prim__eqFloat : Double -> Double -> Int++    prim__eqInt : Int -> Int -> Int++    prim__eqString : String -> String -> Int++    prim__syntactic_eq : (a : Type) -> (b : Type) -> (x : a) -> (y : b) -> Maybe (x = y)++    sequence : Traversable t => Applicative f => (t (f a)) -> f (t a)+++    sequence_ : Foldable t => Applicative f => (t (f a)) -> f ()+++    Eq : Type -> Type+    The Eq interface defines inequality and equality.++    GTE : Nat -> Nat -> Type+    Greater than or equal to++    LTE : Nat -> Nat -> Type+    Proofs that n is less than or equal to m++    gte : Nat -> Nat -> Bool+    Boolean test than one Nat is greater than or equal to another++    lte : Nat -> Nat -> Bool+    Boolean test than one Nat is less than or equal to another++    ord : Char -> Int+    Convert the number to its ASCII equivalent.++    replace : (x = y) -> (P x) -> P y+    Perform substitution in a term according to some equality.++    sym : (l = r) -> r = l+    Symmetry of propositional equality++    trans : (a = b) -> (b = c) -> a = c+    Transitivity of propositional equality++``:search`` does a type-based search, in the spirit of Hoogle. See `Type-directed search (:search) <https://github.com/idris-lang/Idris-dev/wiki/Type-directed-search-%28%3Asearch%29>`_ for more details. Here is an example:++::++    Idris> :search a -> b -> a+    = Prelude.Basics.const : a -> b -> a+    Constant function. Ignores its second argument.++    = assert_smaller : a -> b -> b+    Assert to the totality checker than y is always structurally+    smaller than x (which is typically a pattern argument)++    > malloc : Int -> a -> a+++    > Prelude.pow : Num a => a -> Nat -> a+++    > Prelude.Interfaces.(*) : Num a => a -> a -> a+++    > Prelude.Interfaces.(+) : Num a => a -> a -> a+    ... (More results)++``:search`` can also look for dependent types:++::++    Idris> :search plus (S n) n = plus n (S n)+    < Prelude.Nat.plusSuccRightSucc : (left : Nat) ->+                                      (right : Nat) ->+                                      S (left + right) = left + S right++Loading and reloading Idris code+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++The command ``:l File.idr`` will load File.idr into the+currently-running REPL, and ``:r`` will reload the last file that was+loaded.++Totality+~~~~~~~~++All Idris definitions are checked for totality. The command+``:total <NAME>`` will display the result of that check. If a definition+is not total, this may be due to an incomplete pattern match. If that is+the case, ``:missing`` or ``:miss`` will display the missing cases.++Editing files+~~~~~~~~~~~~~++The command ``:e`` launches your default editor on the current module.+After control returns to Idris, the file is reloaded.++Invoking the compiler+~~~~~~~~~~~~~~~~~~~~~++The current module can be compiled to an executable using the command+``:c <FILENAME>`` or ``:compile <FILENAME>``. This command allows to+specify codegen, so for example JavaScript can be generated using+``:c javascript <FILENAME>``. The ``:exec`` command will compile the+program to a temporary file and run the resulting executable.++IO actions+~~~~~~~~~~++Unlike GHCI, the Idris REPL is not inside of an implicit IO monad. This+means that a special command must be used to execute IO actions.+``:x tm`` will execute the IO action ``tm`` in an Idris interpreter.++Dynamically loading C libraries+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Sometimes, an Idris program will depend on external libraries written in+C. In order to use these libraries from the Idris interpreter, they must+first be dynamically loaded. This is achieved through the+``%dynamic <LIB>`` directive in Idris source files or through the+``:dynamic <LIB>`` command at the REPL. The current set of dynamically+loaded libraries can be viewed by executing ``:dynamic`` with no+arguments. These libraries are available through the Idris FFI in `type+providers <#type-providers>`__ and ``:exec``.++Colours+=======++Idris terms are available in amazing colour! By default, the Idris REPL+uses colour to distinguish between data constructors, types or type+constructors, operators, bound variables, and implicit arguments. This+feature is available on all POSIX-like systems, and there are plans to+allow it to work on Windows as well.++If you do not like the default colours, they can be turned off using the+command++::++    :colour off++and, when boredom strikes, they can be re-enabled using the command++::++    :colour on++To modify a colour, use the command++::++    :colour <CATEGORY> <OPTIONS>++where ``<CATEGORY`` is one of ``keyword``, ``boundvar``, ``implicit``,+``function``, ``type``, ``data``, or ``prompt``, and is a+space-separated list drawn from the colours and the font options. The+available colours are ``default``, ``black``, ``yellow``, ``cyan``,+``red``, ``blue``, ``white``, ``green``, and ``magenta``. If more than+one colour is specified, the last one takes precedence. The available+options are ``dull`` and ``vivid``, ``bold`` and ``nobold``, ``italic``+and ``noitalic``, ``underline`` and ``nounderline``, forming pairs of+opposites. The colour ``default`` refers to your terminal's default+colour.++The colours used at startup can be changed using REPL initialisation+scripts.++Colour can be disabled at startup by the ``--nocolour`` command-line+option.
+ docs/reference/semantic-highlighting.rst view
@@ -0,0 +1,50 @@+****************************************+Semantic Highlighting & Pretty Printing+****************************************++Since ``v0.9.18`` Idris comes with support for semantic highlighting.+When using the ``REPL`` or IDE support, Idris will highlight your code accordingly to its meaning within the Idris structure. A precursor to semantic highlighting support is the pretty printing of definitions to console, LaTeX, or HTML.++The default styling scheme used was inspired by Conor McBride's own set of stylings, informally known as *Conor Colours*.+++Legend+======++The concepts and their default stylings are as follows:+++----------------+---------------+----------------+----------------++| Idris Term     | HTML          | LaTeX          | IDE/REPL       |++================+===============+================+================++| Bound Variable | Purple        | Magenta        |                |++----------------+---------------+----------------+----------------++| Keyword        | Bold          | Underlined     |                |++----------------+---------------+----------------+----------------++| Function       | Green         | Green          |                |++----------------+---------------+----------------+----------------++| Type           | Blue          | Blue           |                |++----------------+---------------+----------------+----------------++| Data           | Red           | Red            |                |++----------------+---------------+----------------+----------------++| Implicit       | Italic Purple | Italic Magenta |                |++----------------+---------------+----------------+----------------+++Pretty Printing+===============++Idris also supports the pretty printing of code to HTML and LaTeX using the commands:+++ ``:pp <latex|html> <width> <function name>``++ ``:pprint <latex|html> <width> <function name>``+++Customisation+=============++If you are not happy with the colours used, the VIM and Emacs editor support allows for customisation of the colours. When pretty printing Idris code as LaTeX and HTML, commands and a CSS style are provided. The colours used by the REPL can be customised through the initialisation script.+++Further Information+===================++Please also see the `Idris Extras <https://github.com/idris-hackers/idris-extras>`_ project for links to editor support, and pre-made style files for LaTeX and HTML.
+ docs/reference/syntax-guide.rst view
@@ -0,0 +1,408 @@+**************+Syntax Guide+**************++Examples are mostly adapted from the Idris tutorial.++Source File Structure+---------------------++Source files consist of:++1. An optional :ref:`syntax-module-headers`.+2. Zero or more :ref:`syntax-imports`.+3. Zero or more declarations, e.g. :ref:`syntax-variables`,+   :ref:`syntax-data-types`, etc.++For example:++.. code:: idris++    module MyModule   -- module header++    import Data.Vect  -- an import++    %default total    -- a directive++    foo : Nat         -- a declaration+    foo = 5++.. _syntax-module-headers:++Module Header+~~~~~~~~~~~~~++A file can start with a module header, introduced by the ``module`` keyword:++.. code-block:: idris++  module Semantics++Module names can be hierarchical, with parts separated by ``.``:++.. code-block:: idris++  module Semantics.Transform++Each file can define only a single module, which includes everything defined in+that file.++Like with declarations, a :ref:`docstring <syntax-comments>` can be used to+provide documentation for a module:++.. code-block:: idris++  ||| Implementation of predicate transformer semantics.+  module Semantics.Transform++.. _syntax-imports:++Imports+~~~~~~~++An ``import`` makes the names in another module available for use by the current+module:++.. code-block:: idris++    import Data.Vect++All the declarations in an imported module are available for use in the file.+In a case where a name is ambiguous --- e.g. because it is imported from+multiple modules, or appears in multiple visible namespaces --- the ambiguity can be resolved using :ref:`syntax-qualified-names`.  (Often, the compiler can+resolve the ambiguity for you, using the types involved.)++Imported modules can be given aliases to make qualified names more compact:++.. code-block:: idris++    import Data.Vect as V++Note that names made visible by import are not, by default, re-exported to+users of the module being written.  This can be done using ``import public``:++.. code-block:: idris++    import public Data.Vect++.. _syntax-variables:++Variables+---------++A variable is always defined by defining its type on one line, and its+value on the next line, using the syntax++::++    <id> : <type>+    <id> = <value>++Examples++.. code:: idris++    x : Int+    x = 100+    hello : String+    hello = "hello"++Types+-----++In Idris, types are first class values. So a type declaration is the+same as just declaration of a variable whose type is ``Type``. In Idris,+variables that denote a type need not be capitalised. Example:++.. code:: idris++    MyIntType : Type+    MyIntType = Int++a more interesting example:++.. code:: idris++    MyListType : Type+    MyListType = List Int++While capitalising types is not required, the rules for generating implicit+arguments mean it is often a good idea.++.. _syntax-data-types:++Data types+~~~~~~~~~~++Idris provides two kinds of syntax for defining data types. The first,+Haskell style syntax, defines a regular algebraic data type. For example++.. code:: idris++    data Either a b = Left a | Right b++or++.. code:: idris++    data List a = Nil | (::) a (List a)++The second, more general kind of data type, is defined using Agda or+GADT style syntax. This syntax defines a data type that is parameterised+by some values (in the ``Vect`` example, a value of type ``Nat`` and a+value of type ``Type``).++.. code:: idris++    data Vect : Nat -> Type -> Type where+      Nil  : Vect Z a+      (::) : (x : a) -> (xs : Vect n a) -> Vect (S n) a++Operators+---------++Arithmetic+~~~~~~~~~~++::++    x + y+    x - y+    x * y+    x / y+    (x * y) + (a / b)++Equality and Relational+~~~~~~~~~~~~~~~~~~~~~~~++::++    x == y+    x /= y+    x >= y+    x > y+    x <= y+    x < y++Conditional+~~~~~~~~~~~++::++    x && y+    x || y+    not x++Conditionals+------------++If Then Else+~~~~~~~~~~~~++::++    if <test> then <true> else <false>++Case Expressions+~~~~~~~~~~~~~~~~++::++    case <test> of+        <case 1>  => <expr>+        <case 2>  => <expr>+        ...+        otherwise => <expr>++Functions+---------++Named+~~~~~++Named functions are defined in the same way as variables, with the type+followed by the definition.++::++    <id> : <argument type> -> <return type>+    <id> arg = <expr>++Example++.. code:: idris++    plusOne : Int -> Int+    plusOne x = x + 1++Functions can also have multiple inputs, for example++.. code:: idris++    makeHello : String -> String -> String+    makeHello first last = "hello, my name is " ++ first ++ " " ++ last++Functions can also have named arguments. This is required if you want to+annotate parameters in a docstring. The following shows the same+``makeHello`` function as above, but with named parameters which are+also annotated in the docstring++.. code:: idris++    ||| Makes a string introducing a person+    ||| @first The person's first name+    ||| @last The person's last name+    makeHello : (first : String) -> (last : String) -> String+    makeHello first last = "hello, my name is " ++ first ++ " " ++ last++Like Haskell, Idris functions can be defined by pattern matching. For+example++.. code:: idris++    sum : List Int -> Int+    sum []        = 0+    sum (x :: xs) = x + (sum xs)++Similarly case analysis looks like++.. code:: idris++    answerString : Bool -> String+    answerString False = "Wrong answer"+    answerString True = "Correct answer"++Dependent Functions+~~~~~~~~~~~~~~~~~~~++Dependent functions are functions where the type of the return value+depends on the input value. In order to define a dependent function,+named parameters must be used, since the parameter will appear in the+return type. For example, consider++.. code:: idris++    zeros : (n : Nat) -> Vect n Int+    zeros Z     = []+    zeros (S k) = 0 :: (zeros k)++In this example, the return type is ``Vect n Int`` which is an+expression which depends on the input parameter ``n``.++Anonymous+~~~~~~~~~++Arguments in anonymous functions are separated by comma.++::++    (\x => <expr>)+    (\x, y => <expr>)++Modifiers+~~~~~~~~~++Visibility+^^^^^^^^^^++::++    public export+    export+    private++Totality+^^^^^^^^++::++    total+    implicit+    partial+    covering++Options+^^^^^^^++::++    %export+    %hint+    %no_implicit+    %error_handler+    %error_reverse+    %assert_total+    %reflection+    %specialise [<name list>]++Misc+----++.. _syntax-qualified-names:++Qualified Names+~~~~~~~~~~~~~~~++If multiple declarations with the same name are visible, using the name can+result in an ambiguous situation.  The compiler will attempt to resolve the+ambiguity using the types involved.  If it's unable --- for example, because+the declarations with the same name also have the same type signatures --- the+situation can be cleared up using a *qualified name*.++A qualified name has the symbol's namespace prefixed, separated by a ``.``:++.. code-block:: idris++  Data.Vect.length++This would specifically reference a ``length`` declaration from ``Data.Vect``.++Qualified names can be written using two different shorthands:++1. Names in modules that are :ref:`imported <syntax-imports>` using an alias+   can be qualified by the alias.++2. The name can be qualified by the *shortest unique suffix* of the+   namespace in question.  For example, the ``length`` case above can likely+   be shortened to ``Vect.length``.++.. _syntax-comments:++Comments+~~~~~~~~++::++    -- Single Line+    {- Multiline -}+    ||| Docstring (goes before definition)++Multi line String literals+~~~~~~~~~~~~~~~~~~~~~~~~~~++::++    foo = """+    this is a+    string literal"""++.. _syntax-directives:++Directives+----------++::++    %lib <path>+    %link <path>+    %flag <path>+    %include <path>+    %hide <function>+    %freeze <name>+    %access <accessibility>+    %default <totality>+    %logging <level 0--11>+    %dynamic <list of libs>+    %name <list of names>+    %error_handlers <list of names>+    %language <extension>
+ docs/reference/tactics.rst view
@@ -0,0 +1,217 @@+****************************************+DEPRECATED: Tactics and Theorem Proving+****************************************++.. warning::+   The interactive theorem-proving interface documented here has been+   deprecated in favor of :ref:`elaborator-reflection`.++Idris supports interactive theorem proving, and the analyse of context+through holes.  To list all unproven holes, use the command ``:m``.+This will display their qualified names and the expected types. To+interactively prove a holes, use the command ``:p name`` where ``name``+is the hole. Once the proof is complete, the command ``:a`` will append+it to the current module.++Once in the interactive prover, the following commands are available:++Basic commands+==============++-  ``:q`` - Quits the prover (gives up on proving current lemma).+-  ``:abandon`` - Same as :q+-  ``:state`` - Displays the current state of the proof.+-  ``:term`` - Displays the current proof term complete with its+   yet-to-be-filled holes (is only really useful for debugging).+-  ``:undo`` - Undoes the last tactic.+-  ``:qed`` - Once the interactive theorem prover tells you "No more+   goals," you get to type this in celebration! (Completes the proof and+   exits the prover)++Commonly Used Tactics+=====================++Compute+-------++-  ``compute`` - Normalises all terms in the goal (note: does not+   normalise assumptions)++::++    ----------                 Goal:                  ----------+     (Vect (S (S Z + (S Z) + (S n))) Nat) -> Vect (S (S (S (S n)))) Nat+    -lemma> compute+    ----------                 Goal:                  ----------+     (Vect (S (S (S (S n)))) Nat) -> Vect (S (S (S (S n)))) Nat+    -lemma>++Exact+-----++-  ``exact`` - Provide a term of the goal type directly.++::++    ----------                 Goal:                  ----------+     Nat+    -lemma> exact Z+    lemma: No more goals.+    -lemma>++Refine+------++-  ``refine`` - Use a name to refine the goal. If the name needs+   arguments, introduce them as new goals.++Trivial+-------++-  ``trivial`` - Satisfies the goal using an assumption that matches its+   type.++::++    ----------              Assumptions:              ----------+     value : Nat+    ----------                 Goal:                  ----------+     Nat+    -lemma> trivial+    lemma: No more goals.+    -lemma>++Intro+-----++-  ``intro`` - If your goal is an arrow, turns the left term into an+   assumption.++::++    ----------                 Goal:                  ----------+     Nat -> Nat -> Nat+    -lemma> intro+    ----------              Assumptions:              ----------+     n : Nat+    ----------                 Goal:                  ----------+     Nat -> Nat+    -lemma>++You can also supply your own name for the assumption:++::++    ----------                 Goal:                  ----------+    Nat -> Nat -> Nat+    -lemma> intro number+    ----------              Assumptions:              ----------+     number : Nat+    ----------                 Goal:                  ----------+    Nat -> Nat+++Intros+------++-  ``intros`` - Exactly like intro, but it operates on all left terms at+   once.++::++    ----------                 Goal:                  ----------+     Nat -> Nat -> Nat+    -lemma> intros+    ----------              Assumptions:              ----------+     n : Nat+     m : Nat+    ----------                 Goal:                  ----------+     Nat+    -lemma>++let+---++-  ``let`` - Introduces a new assumption; you may use current+   assumptions to define the new one.++::++    ----------              Assumptions:              ----------+     n : Nat+    ----------                 Goal:                  ----------+     BigInt+    -lemma> let x = toIntegerNat n+    ----------              Assumptions:              ----------+     n : Nat+      x = toIntegerNat n: BigInt+    ----------                 Goal:                  ----------+     BigInt+    -lemma>++rewrite+-------++-  ``rewrite`` - Takes an expression with an equality type (x = y), and+   replaces all instances of x in the goal with y. Is often useful in+   combination with 'sym'.++::++    ----------              Assumptions:              ----------+     n : Nat+     a : Type+     value : Vect Z a+    ----------                 Goal:                  ----------+     Vect (mult n Z) a+    -lemma> rewrite sym (multZeroRightZero n)+    ----------              Assumptions:              ----------+     n : Nat+     a : Type+     value : Vect Z a+    ----------                 Goal:                  ----------+     Vect Z a+    -lemma>++induction+---------++-  ``induction`` - (``Note that this is still experimental`` and you may+   get strange results and error messages. We are aware of these and+   will finish the implementation eventually!) Prove the goal by+   induction. Each constructor of the datatype becomes a goal.+   Constructors with recursive arguments become induction steps, while+   simple constructors become base cases. Note that this only works for+   datatypes that have eliminators: a datatype definition must have the+   ``%elim`` modifier.+++sourceLocation+--------------++-  ``sourceLocation`` - Solve the current goal with information about+   the location in the source code where the tactic was invoked. This is+   mostly for embedded DSLs and programmer tools like assertions that+   need to know where they are called. See+   ``Language.Reflection.SourceLocation`` for more information.++Less commonly-used tactics+==========================++-  ``applyTactic`` - Apply a user-defined tactic. This should be a+   function of type ``List (TTName, Binder TT) -> TT -> Tactic``, where+   the first argument represents the proof context and the second+   represents the goal. If your tactic will produce a proof term+   directly, use the ``Exact`` constructor from ``Tactic``.+-  ``attack`` - ?+-  ``equiv`` - Replaces the goal with a new one that is convertible with+   the old one+-  ``fill`` - ?+-  ``focus`` - ?+-  ``mrefine`` - Refining by matching against a type+-  ``reflect`` - ?+-  ``solve`` - Takes a guess with the correct type and fills a hole with+   it, closing a proof obligation. This happens automatically in the+   interactive prover, so ``solve`` is really only relevant in tactic+   scripts used for helping implicit argument resolution.+-  ``try`` - ?
+ docs/reference/type-directed-search.rst view
@@ -0,0 +1,336 @@+*********************************+Type Directed Search ``:search``+*********************************++Idris' ``:search`` command searches for terms according to their+approximate type signature (much like+`Hoogle <http://www.haskell.org/hoogle/>`__ for Haskell). For+example::++    Idris> :search e -> List e -> List e+    = Prelude.List.(::) : a -> List a -> List a+    Cons cell++    = Prelude.List.intersperse : a -> List a -> List a+    Insert some separator between the elements of a list.++    > Prelude.List.delete : Eq a => a -> List a -> List a+++    < assert_smaller : a -> b -> b+    Assert to the totality checker than y is always structurally+    smaller than x (which is typically a pattern argument)++    < Prelude.Basics.const : a -> b -> a+    Constant function. Ignores its second argument.++The best results are listed first. As we can see, ``(::)`` and+``intersperse`` are exact matches; the ``=`` symbol to the left of those+results tells us the types of ``(::)`` and ``intersperse`` are+effectively the same as the type that was searched.++The next result is ``delete``, whose type is more specific than the type+that was searched; that's indicated by the ``>`` symbol. If we had a+function with the signature ``e -> List e -> List e``, we could have+given it the type ``Eq a => a -> List a -> List a``, but not necessarily+the other way around.++The final two results, ``assert_smaller`` and ``const``, have types more+general than the type that was searched, and so they have ``<`` symbols+to their left. For example, ``e -> List e -> List e`` would be a valid+type for ``assert_smaller``. The correspondence for ``const`` is more+complicated than any of the four previous results. ``:search`` shows+this result because we could change the order of the arguments! That is,+the following definition would be legal:++.. code:: idris++    f : e -> List e -> List e+    f x xs = const xs x++About :search results+---------------------++:search's functionality is based on the notion of type isomorphism.+Informally, two types are isomorphic if we can identify terms of one+type exactly with terms of the other. For example, we can consider the+types ``Nat -> a -> List a`` and ``a -> Nat -> List a`` to be+isomorphic, because if we have ``f : Nat -> a -> List a``, then+``flip f : a -> Nat -> List a``. Similarly, if+``g : a -> Nat -> List a``, then ``flip g : Nat -> a -> List a``.++With :search, we create a partial order on types; that is, given two+types ``A`` and ``B``, we may choose to say that ``A <= B``, ``A >= B``,+or both (in which case we say ``A == B``), or neither. For :search, we+say that ``A >= B`` if all of the terms inhabiting ``A`` correspond to+terms of ``B``, but it need not necessarily be the case that *all* the+terms of ``B`` correspond to terms of ``A``. Here's an example:++::++    a -> a            >=          Nat -> Nat++The left-hand type has just a single inhabitant, ``id``, which+corresponds to the term ``id {a = Nat}``, which has the right-hand type.+However, there are various terms inhabiting the right-hand type (such as+``S``) which cannot correspond with terms of type ``a -> a``.++We can consider the partial order for ``:search`` to be, in some sense,+inductively generated by several classes of "edits" which are described+below.++Possible edits+~~~~~~~~~~~~~~++Here is a simple approximate list of the edits that are possible in+``:search``. They are not entirely formal, and do not necessarily+reflect the ``:search`` command's actual behavior. For example, the+*argument application* rule may be used directly on arguments that are+bound after other arguments, without using several applications of the+*argument transposition* rule.++-  **Argument transposition**++   ::++          A : Type          B : Type           a : A, b : B  |-  M : Type+       ----------------------------------------------------------------------------+       (x : A) -> (y : B) -> [x,y/a,b]M      ==    (y : B) -> (x : A) -> [x,y/a,b]M++   Score: 1 point++Example:++::++    a -> Vect n a -> Vect (S n) a    ==    Vect n a -> a -> Vect (S n) a++Note that in order for it to make sense to change the order of+arguments, neither of the arguments' types may depend on the value bound+by the other argument!++-  **Symmetry of equality**++   ::++       A = B : Type      t : Type  |-  M : Type+       ----------------------------------------+        [A = B/t]M        ==       [B = A/t]M++   Score: 1 point++Example:++::++    (x,y,z : Nat) -> x + (y + z) = (x + y) + z+                       ==+    (x,y,z : Nat) -> (x + y) + z = x + (y + z)++Note that this rule means that we can flip equalities anywhere they+occur (i.e., not only in the return type).++-  **Argument application**++   ::++         e : A  |-  M : Type        y1 : T1, ..., yn : Tn  |-  x : A+       -----------------------------------------------------------------+       (z : A) -> [z/e]M     >=   (y1 : T1) -> ... -> (yn :Tn) -> [x/e]M++   Score: <= : 3 points, >= : 9 points++Examples:++::++    a -> a            >=    Nat -> Nat+    a -> a            >=    List e -> List e+    Vect k (Fin k)    >=    Vect 5 (Fin 5)++Note that the ``n`` shown in the scheme above may be 0; that is, there+are no Pi terms to be added on the right side. For example, that's the+case for the first example shown above. This is probably the most+important, and most widely used, rule of all.++-  **Type class application**++   ::++       C : Type -> TypeClass+       ,   y1 : T1, ..., yn : Tn  |-  A : Type, instance : C A+       ,   t : Type  |- M : Type+       -----------------------------------------------------------------+       C a => [a/t]M     >=      (y1 : T1) -> ... -> (yn : Tn) -> [A/t]M++   Score: <= : 4 points, >= : 12 points++Examples++::++    Ord a => a                           >=    Int+    Show (List e) => List e -> String    >=    Show a => List a -> String++This rule is used by looking at the instances for a particular type+class. While the scheme is shown only for single-parameter type classes,+it naturally generalizes to multi-parameter type classes. This rule is+particularly useful in conjunction with argument application. Again,+note that the ``n`` in the scheme above may be 0.++-  **Type class introduction**++   ::++       t : Type |- M : Type      C : Type -> TypeClass+       -----------------------------------------------+       (t : Type) -> M      >=      C t => M++   Score: <= : 2 points, >= : 6 points++Example:++::++    a -> a -> Bool    >=    Eq a => a -> a -> Bool++Scoring and listing search results+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++When a type ``S`` is searched, the type is compared against the types of+all of the terms which are currently in context. When :search compares+two types ``S`` and ``T``, it essentially tries to find a chain of+inequalities++::++       R1    R2     Rn    Rn+1+    S  <= A1 <= ... <= An <= T++using the edit rules listed above. It also tries to find chains going+the other way (i.e., showing ``S >= T``) as well. Each rule has an+associated score which indicates how drastic of a change the rule+corresponds to. These scores are listed above. Note that for the rules+which are not symmetric, the score depends on the direction in which the+rule is used. Finding types which are more general that the searched+typed (``S <= T``) is preferred to finding types which are less general.++The score for the entire chain is, at minimum, the sum of the scores of+the individual rules (some non-linear interactions may be added). The+:search function tries to find the chain between ``S`` and ``T`` which+results in the lowest score, and this is the score associated to the+search result for ``T``.++Search results are listed in order of ascending score. The symbol which+is shown along with the search result reflects the type of the chain+which resulted in the minimum score.++Implementation of :search+-------------------------++Practically, naive and undirected application of the rules enumerated+above is not possible; not only is this obviously inefficient, but the+two application rules (particularly *argument application*) are really+impossible to use without context given by other types. Therefore, we+use a heuristic algorithm that is meant to be practical, though it might+not find ways to relate two types which may actually be related by the+rules listed above.++Suppose we wish to match two types, ``S`` and ``T``. We think of the+problem as a non-deterministic state machine. There is a ``State``+datatype which keeps track of how well we've matched ``S`` and ``T`` so+far. It contains:++-  Names of argument variables (Pi-bound variables) in either type which+   have yet to be matched+-  A directed acyclic graph (DAG) of arguments (Pi-bindings) for ``S``+   and ``T`` which have yet to be matched+-  A list of typeclass constraints for ``S`` and ``T`` which have yet to+   be matched+-  A record of the rules which have been used so far to get to this+   point++A function ``nextSteps : State -> [State]`` finds the next states which+may follow from a given state. Some states, where everything has been+matched, are considered final. The algorithm can be roughly broken down+into multiple stages; if we start from having two types, ``S`` and+``T``, which we wish to match, they are as follows:++1. For each of ``S`` and ``T``, split the types up into their return+   types and directed acyclic graphs of the arguments, where there is an+   edge from argument A to argument B if the term bound in A appears in+   the type of B. The topological sorts of the DAG represent all the+   possible ways in which the arguments may be permuted.+2. For type ``T``, recursively find (saturated) uses of the ``=`` type+   constructor and produce a list of modified versions of ``T``+   containing all possible flips of the ``=`` constructor (this+   corresponds to the *symmetry of equality rule*).+3. For each modified type for ``T``, try to unify the return type of the+   modified ``T`` with ``S``, considering arguments from both ``S`` and+   ``T`` to be holes, so that the unifier may match pieces of the two+   types. For each modified version of ``T`` where this succeeds, an+   initial ``State`` can be made. The arguments and typeclasses are+   updated accordingly with the results of unification. The remainder of+   the algorithm involves applying ``nextSteps`` to these states until+   either no states remain (corresponding to no path from ``S`` to+   ``T``) or a final state is found. ``nextSteps`` also has several+   stages:+4. Try to unify arguments of ``S`` with arguments of ``T``, much like is+   done with the return types. We work "backwards" through the+   arguments: we try matching all remaining arguments of ``S`` which+   lack outgoing edges in the DAG of remaining arguments (that is, the+   bound value doesn't appear in the type of any other remaining+   arguments) with the all of the corresponding remaining arguments of+   ``T``. This is done recursively until no arguments remain for both+   ``S`` and ``T``; otherwise, we give up at this point. This step+   corresponds to application of the *argument application rule*, as+   well as the *argument transposition* rule.+5. Now, we try to match the type classes. First, we take all possible+   subsets of type class constraints for ``S`` and ``T``. So if ``S``+   and ``T`` have a total of ``n`` type class constraints, this produces+   ``2^n`` states for every state, and this quickly becomes infeasible+   as ``n`` grows large. This is probably the biggest bottleneck of the+   algorithm at the moment. This step corresponds to applications of the+   *type class introduction* rule.+6. Try to match type class constraints for ``S`` with those for ``T``.+   We attempt to unify each type class constraint for ``S`` with each+   constraint for ``T``. This may result in applications of the *type+   class application* rule. Once we are unable to match any more type+   class constraints between ``S`` and ``T``, we proceed to the final+   step.+7. Try instantiating type classes with their instances (in either ``S``+   or ``T``). This corresponds to applications of the *type class+   application* rule. After instantiating a type class, we hopefully+   open up more opportunities to match typeclass constraints of ``S``+   with those of ``T``, so we return to the previous step.++The code for :search is located in the `Idris.TypeSearch+module <https://github.com/idris-lang/Idris-dev/blob/master/src/Idris/TypeSearch.hs>`__.++Aggregating results+~~~~~~~~~~~~~~~~~~~++The search for chains of rules/edits which relate two types can be+viewed as a shortest path problem where nodes correspond to types and+edges correspond to rules relating two types. The weights or distances+on each edge correspond to the score of each rule. We then may imagine+that we have a single start node, our search type ``S``, and several+final nodes: all of the types for terms which are currently in context.+The problem, then, is to find the shortest paths (where they exist) to+all of the final nodes. In particular, we wish to find the "closest"+types (those with the minimum score) first, as we'd like to display them+first.++This problem nicely maps to usage of Dijkstra's algorithm. We search for+all types simultaneously so we can find the closest ones with the+minimum amount of work. In practice, this results in using a priority+queue of priority queues. We first ask "which goal type should we work+on next?", and then ask "which state should we expand upon next?" By+using this strategy, the best results can be shown quickly, even if it+takes a bit of time to find worse results (or at least rule them out).++Miscellaneous Notes+-------------------++Whether arguments are explicit or implicit does not affect search+results.
+ docs/reference/uniqueness-types.rst view
@@ -0,0 +1,252 @@+****************+Uniqueness Types+****************++Uniqueness Types are an experimental feature available from Idris+0.9.15. A value with a unique type is guaranteed to have *at most one*+reference to it at run-time, which means that it can safely be updated+in-place, reducing the need for memory allocation and garbage+collection. The motivation is that we would like to be able to write+reactive systems, programs which run in limited memory environments,+device drivers, and any other system with hard real-time requirements,+ideally while giving up as little high level conveniences as possible.++They are inspired by linear types, `Uniqueness Types+<https://en.wikipedia.org/wiki/Uniqueness_type>`__ in the `Clean+<http://wiki.clean.cs.ru.nl/Clean>`__ programming language, and+ownership types and borrowed pointers in the `Rust+<https://www.rust-lang.org/>`__ programming language.++Some things we hope to be able to do eventually with uniqueness types+include:++-  Safe, pure, in-place update of arrays, lists, etc+-  Provide guarantees of correct resource usage, state transitions, etc+-  Provide guarantees that critical program fragments will *never*+   allocate++Using Uniqueness+================++If ``x : T`` and ``T : UniqueType``, then there is at most one reference+to ``x`` at any time during run-time execution. For example, we can+declare the type of unique lists as follows:++.. code-block:: idris++    data UList : Type -> UniqueType where+         Nil   : UList a+         (::)  : a -> UList a -> UList a++If we have a value ``xs : UList a``, then there is at most one+reference to ``xs`` at run-time. The type checker preserves this+guarantee by ensuring that there is at most one reference to any value+of a unique type in a pattern clause. For example, the following+function definition would be valid:++.. code-block:: idris++    umap : (a -> b) -> UList a -> UList b+    umap f [] = []+    umap f (x :: xs) = f x :: umap f xs++In the second clause, ``xs`` is a value of a unique type, and only+appears once on the right hand side, so this clause is valid. Not only+that, since we know there can be no other reference to the ``UList a``+argument, we can reuse its space for building the result! The compiler+is aware of this, and compiles this definition to an in-place update+of the list.++The following function definition would not be valid (even assuming an+implementation of ``++``), however, since ``xs`` appears twice:++.. code-block:: idris++    dupList : UList a -> UList a+    dupList xs = xs ++ xs++This would result in a shared pointer to ``xs``, so the typechecker+reports:++.. code-block:: idris++    unique.idr:12:5:Unique name xs is used more than once++If we explicitly copy, however, the typechecker is happy:++.. code-block:: idris++    dup : UList a -> UList a+    dup [] = []+    dup (x :: xs) = x :: x :: dup xs++Note that it's fine to use ``x`` twice, because ``a`` is a ``Type``,+rather than a ``UniqueType``.++There are some other restrictions on where a ``UniqueType`` can+appear, so that the uniqueness property is preserved. In particular,+the type of the function type, ``(x : a) -> b`` depends on the type of+``a`` or ``b`` - if either is a ``UniqueType``, then the function type+is also a ``UniqueType``. Then, in a data declaration, if the type+constructor builds a ``Type``, then no constructor can have a+``UniqueType``. For example, the following definition is invalid,+since it would embed a unique value in a possible non-unique value:++.. code-block:: idris++    data BadList : UniqueType -> Type where+         Nil   : {a : UniqueType} -> BadList a+         (::)  : {a : UniqueType} -> a -> BadList a -> BadList a++Finally, types may be polymorphic in their uniqueness, to a limited+extent. Since ``Type`` and ``UniqueType`` are different types, we are+limited in how much we can use polymorphic functions on unique types.+For example, if we have function composition defined as follows:++.. code-block:: idris++    (.) : {a, b, c : Type} -> (b -> c) -> (a -> b) -> a -> c+    (.) f g x = f (g x)++And we have some functions over unique types:++.. code-block:: idris++    foo : UList a -> UList b+    bar : UList b -> UList c++Then we cannot compose ``foo`` and ``bar`` as ``bar . foo``, because+``UList`` does not compute a ``Type``! Instead, we can define+composition as follows:++.. code-block:: idris++    (.) : {a, b, c : Type*} -> (b -> c) -> (a -> b) -> a -> c+    (.) f g x = f (g x)++The ``Type*`` type stands for either unique or non-unique types. Since+such a function may be passed a ``UniqueType``, any value of type+``Type*`` must also satisfy the requirement that it appears at most+once on the right hand side.++Borrowed Types+--------------++It quickly becomes obvious when working with uniqueness types that+having only one reference at a time can be painful. For example, what+if we want to display a list before updating it?++.. code-block:: idris++    showU : Show a => UList a -> String+    showU xs = "[" ++ showU' xs ++ "]" where+      showU' : UList a -> String+      showU' [] = ""+      showU' [x] = show x+      showU' (x :: xs) = show x ++ ", " ++ showU' xs++This is a valid definition of ``showU``, but unfortunately it consumes+the list! So the following function would be invalid:++.. code-block:: idris++    printAndUpdate : UList Int -> IO ()+    printAndUpdate xs = do putStrLn (showU xs)+                           let xs' = umap (*2) xs -- xs no longer available!+                           putStrLn (showU xs')++Still, one would hope to be able to display a unique list without+problem, since it merely *inspects* the list; there are no updates. We+can achieve this, using the notion of *borrowing*. A Borrowed type is+a Unique type which can be inspected at the top level (by pattern+matching, or by *lending* to another function) but no further. This+ensures that the internals (i.e. the arguments to top level patterns)+will not be passed to any function which will update them.++``Borrowed`` converts a ``UniqueType`` to a ``BorrowedType``. It is+defined as follows (along with some additional rules in the+typechecker):++.. code-block:: idris++    data Borrowed : UniqueType -> BorrowedType where+         Read : {a : UniqueType} -> a -> Borrowed a++    implicit+    lend : {a : UniqueType} -> a -> Borrowed a+    lend x = Read x++A value can be "lent" to another function using ``lend``. Arguments to+``lend`` are not counted by the type checker as a reference to a unique+value, therefore a value can be lent as many times as desired. Using+this, we can write ``showU`` as follows:++.. code-block:: idris++    showU : Show a => Borrowed (UList a) -> String+    showU xs = "[" ++ showU' xs ++ "]" where+      showU' : Borrowed (UList a) -> String+      showU' [] = ""+      showU' [x] = show x+      showU' (Read (x :: xs)) = show x ++ ", " ++ showU' (lend xs)++Unlike a unique value, a borrowed value may be referred to as many+times as desired. However, there is a restriction on how a borrowed+value can be used. After all, much like a library book or your+neighbour's lawnmower, if a function borrows a value it is expected to+return it in exactly the condition in which it was received!++The restriction is that when a ``Borrowed`` type is matched, any+pattern variables under the ``Read`` which have a unique type may not+be referred to at all on the right hand side (unless they are+themselves ``lent`` to another function).++Uniqueness information is stored in the type, and in particular in+function types. Once we're in a unique context, any new function which+is constructed will be required to have unique type, which prevents+the following sort of bad program being implemented:++.. code-block:: idris++    foo : UList Int -> IO ()+    foo xs = do let f = \x : Int => showU xs+                putStrLn $ free xs+                putStrLn $ f 42+                return ()++Since ``lend`` is implicit, in practice for functions to lend and borrow+values merely requires the argument to be marked as ``Borrowed``. We can+therefore write ``showU`` as follows:++.. code-block:: idris++    showU : Show a => Borrowed (UList a) -> String+    showU xs = "[" ++ showU' xs ++ "]" where+      showU' : Borrowed (UList a) -> String+      showU' [] = ""+      showU' [x] = show x+      showU' (x :: xs) = show x ++ ", " ++ showU' xs++Problems/Disadvantages/Still to do...+-------------------------------------++This is a work in progress, there is lots to do. The most obvious+problem is the loss of abstraction. On the one hand, we have more+precise control over memory usage with ``UniqueType`` and+``BorrowedType``, but they are not in general compatible with+functions polymorphic over ``Type``. In the short term, we can start+to write reactive and low memory systems with this, but longer term it+would be nice to support more abstraction.++We also haven't checked any of the metatheory, so this could all be+fatally flawed! The implementation is based to a large extent on+`Uniqueness Typing Simplified+<http://lambda-the-ultimate.org/node/2708>`__, by de Vries et al, so+there is reason to believe things should be fine, but we still have to+do the work.++Much as there are with linear types, there are some annoyances when+trying to prove properties of functions with unique types (for+example, what counts as a use of a value). Since we require *at most*+one use of a value, rather than *exactly* one, this seems to be less+of an issue in practice, but still needs thought.
+ docs/tutorial/conclusions.rst view
@@ -0,0 +1,54 @@+.. _sect-concs:++***************+Further Reading+***************++Further information about Idris programming, and programming with+dependent types in general, can be obtained from various sources:++-  The Idris web site (http://www.idris-lang.org/) and by asking+   questions on the mailing list.++-  The IRC channel ``#idris``, on+   `chat.freenode.net <http://chat.freenode.net>`__.++- The wiki (https://github.com/idris-lang/Idris-dev/wiki/) has further+   user provided information, in particular:++   -  https://github.com/idris-lang/Idris-dev/wiki/Manual++   -  https://github.com/idris-lang/Idris-dev/wiki/Language-Features++- Examining the prelude and exploring the ``samples`` in the+   distribution. The Idris source can be found online at:+   https://github.com/idris-lang/Idris-dev.++-  Existing projects on the ``Idris Hackers`` web space:+   http://idris-hackers.github.io.++- Various papers (e.g. [1]_, [2]_, and [3]_).  Although these mostly+   describe older versions of Idris.++.. [1] Edwin Brady and Kevin Hammond. 2012. Resource-Safe systems+       programming with embedded domain specific languages. In+       Proceedings of the 14th international conference on Practical+       Aspects of Declarative Languages (PADL'12), Claudio Russo and+       Neng-Fa Zhou (Eds.). Springer-Verlag, Berlin, Heidelberg,+       242-257. DOI=10.1007/978-3-642-27694-1_18+       http://dx.doi.org/10.1007/978-3-642-27694-1_18++.. [2] Edwin C. Brady. 2011. IDRIS ---: systems programming meets full+       dependent types. In Proceedings of the 5th ACM workshop on+       Programming languages meets program verification (PLPV+       '11). ACM, New York, NY, USA,+       43-54. DOI=10.1145/1929529.1929536+       http://doi.acm.org/10.1145/1929529.1929536++.. [3] Edwin C. Brady and Kevin Hammond. 2010. Scrapping your+       inefficient engine: using partial evaluation to improve+       domain-specific language implementation. In Proceedings of the+       15th ACM SIGPLAN international conference on Functional+       programming (ICFP '10). ACM, New York, NY, USA,+       297-308. DOI=10.1145/1863543.1863587+       http://doi.acm.org/10.1145/1863543.1863587
+ docs/tutorial/index.rst view
@@ -0,0 +1,35 @@+.. _tutorial-index:++##################+The Idris Tutorial+##################++This is the Idris Tutorial. It will teach you about programming in the Idris Language.++.. note::+   The documentation for Idris has been published under the Creative+   Commons CC0 License. As such to the extent possible under law, *The+   Idris Community* has waived all copyright and related or neighboring+   rights to Documentation for Idris.++   More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/+++.. toctree::+   :maxdepth: 1++   introduction+   starting+   typesfuns+   interfaces+   modules+   packages+   testing+   interp+   views+   theorems+   provisional+   interactive+   syntax+   miscellany+   conclusions
+ docs/tutorial/interactive.rst view
@@ -0,0 +1,258 @@+.. _sect-interactive:++*******************+Interactive Editing+*******************++By now, we have seen several examples of how Idris’ dependent type+system can give extra confidence in a function’s correctness by giving+a more precise description of its intended behaviour in its *type*. We+have also seen an example of how the type system can help with EDSL+development by allowing a programmer to describe the type system of an+object language. However, precise types give us more than verification+of programs — we can also exploit types to help write programs which+are *correct by construction*.++The Idris REPL provides several commands for inspecting and+modifying parts of programs, based on their types, such as case+splitting on a pattern variable, inspecting the type of a+hole, and even a basic proof search mechanism. In this+section, we explain how these features can be exploited by a text+editor, and specifically how to do so in `Vim+<https://github.com/idris-hackers/idris-vim>`_. An interactive mode+for `Emacs <https://github.com/idris-hackers/idris-mode>`_ is also+available.+++Editing at the REPL+===================++The REPL provides a number of commands, which we will describe+shortly, which generate new program fragments based on the currently+loaded module. These take the general form++::++    :command [line number] [name]++That is, each command acts on a specific source line, at a specific+name, and outputs a new program fragment. Each command has an+alternative form, which *updates* the source file in-place:++::++    :command! [line number] [name]++When the REPL is loaded, it also starts a background process which+accepts and responds to REPL commands, using ``idris --client``. For+example, if we have a REPL running elsewhere, we can execute commands+such as:++::++    $ idris --client ':t plus'+    Prelude.Nat.plus : Nat -> Nat -> Nat+    $ idris --client '2+2'+    4 : Integer++A text editor can take advantage of this, along with the editing+commands, in order to provide interactive editing support.++Editing Commands+================++:addclause+----------++The ``:addclause n f`` command (abbreviated ``:ac n f``) creates a+template definition for the function named ``f`` declared on line+``n``.  For example, if the code beginning on line 94 contains:++.. code-block:: idris++    vzipWith : (a -> b -> c) ->+               Vect n a -> Vect n b -> Vect n c++then ``:ac 94 vzipWith`` will give:++.. code-block:: idris++    vzipWith f xs ys = ?vzipWith_rhs++The names are chosen according to hints which may be given by a+programmer, and then made unique by the machine by adding a digit if+necessary. Hints can be given as follows:++.. code-block:: idris++    %name Vect xs, ys, zs, ws++This declares that any names generated for types in the ``Vect`` family+should be chosen in the order ``xs``, ``ys``, ``zs``, ``ws``.++:casesplit+----------++The ``:casesplit n x`` command, abbreviated ``:cs n x``, splits the+pattern variable ``x`` on line ``n`` into the various pattern forms it+may take, removing any cases which are impossible due to unification+errors. For example, if the code beginning on line 94 is:++.. code-block:: idris++    vzipWith : (a -> b -> c) ->+               Vect n a -> Vect n b -> Vect n c+    vzipWith f xs ys = ?vzipWith_rhs++then ``:cs 96 xs`` will give:++.. code-block:: idris++    vzipWith f [] ys = ?vzipWith_rhs_1+    vzipWith f (x :: xs) ys = ?vzipWith_rhs_2++That is, the pattern variable ``xs`` has been split into the two+possible cases ``[]`` and ``x :: xs``. Again, the names are chosen+according to the same heuristic. If we update the file (using+``:cs!``) then case split on ``ys`` on the same line, we get:++.. code-block:: idris++    vzipWith f [] [] = ?vzipWith_rhs_3++That is, the pattern variable ``ys`` has been split into one case+``[]``, Idris having noticed that the other possible case ``y ::+ys`` would lead to a unification error.++:addmissing+-----------++The ``:addmissing n f`` command, abbreviated ``:am n f``, adds the+clauses which are required to make the function ``f`` on line ``n``+cover all inputs. For example, if the code beginning on line 94 is++.. code-block:: idris++    vzipWith : (a -> b -> c) ->+               Vect n a -> Vect n b -> Vect n c+    vzipWith f [] [] = ?vzipWith_rhs_1++then ``:am 96 vzipWith`` gives:++.. code-block:: idris++    vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2++That is, it notices that there are no cases for non-empty vectors,+generates the required clauses, and eliminates the clauses which would+lead to unification errors.++:proofsearch+------------++The ``:proofsearch n f`` command, abbreviated ``:ps n f``, attempts to+find a value for the hole ``f`` on line ``n`` by proof search,+trying values of local variables, recursive calls and constructors of+the required family. Optionally, it can take a list of *hints*, which+are functions it can try applying to solve the hole. For+example, if the code beginning on line 94 is:++.. code-block:: idris++    vzipWith : (a -> b -> c) ->+               Vect n a -> Vect n b -> Vect n c+    vzipWith f [] [] = ?vzipWith_rhs_1+    vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2++then ``:ps 96 vzipWith_rhs_1`` will give++.. code-block:: idris++    []++This works because it is searching for a ``Vect`` of length 0, of+which the empty vector is the only possibility. Similarly, and perhaps+surprisingly, there is only one possibility if we try to solve ``:ps+97 vzipWith_rhs_2``:++.. code-block:: idris++    f x y :: (vzipWith f xs ys)++This works because ``vzipWith`` has a precise enough type: The+resulting vector has to be non-empty (a ``::``); the first element+must have type ``c`` and the only way to get this is to apply ``f`` to+``x`` and ``y``; finally, the tail of the vector can only be built+recursively.++:makewith+---------++The ``:makewith n f`` command, abbreviated ``:mw n f``, adds a+``with`` to a pattern clause. For example, recall ``parity``. If line+10 is:++.. code-block:: idris++    parity (S k) = ?parity_rhs++then ``:mw 10 parity`` will give:++.. code-block:: idris++    parity (S k) with (_)+      parity (S k) | with_pat = ?parity_rhs++If we then fill in the placeholder ``_`` with ``parity k`` and case+split on ``with_pat`` using ``:cs 11 with_pat`` we get the following+patterns:++.. code-block:: idris++      parity (S (plus n n)) | even = ?parity_rhs_1+      parity (S (S (plus n n))) | odd = ?parity_rhs_2++Note that case splitting has normalised the patterns here (giving+``plus`` rather than ``+``). In any case, we see that using+interactive editing significantly simplifies the implementation of+dependent pattern matching by showing a programmer exactly what the+valid patterns are.++Interactive Editing in Vim+==========================++The editor mode for Vim provides syntax highlighting, indentation and+interactive editing support using the commands described above.+Interactive editing is achieved using the following editor commands,+each of which update the buffer directly:++- ``\d`` adds a template definition for the name declared on the+   current line (using ``:addclause``).++- ``\c`` case splits the variable at the cursor (using+   ``:casesplit``).++- ``\m`` adds the missing cases for the name at the cursor (using+   ``:addmissing``).++- ``\w`` adds a ``with`` clause (using ``:makewith``).++- ``\o`` invokes a proof search to solve the hole under the+   cursor (using ``:proofsearch``).++- ``\p`` invokes a proof search with additional hints to solve the+   hole under the cursor (using ``:proofsearch``).++There are also commands to invoke the type checker and evaluator:++- ``\t`` displays the type of the (globally visible) name under the+   cursor. In the case of a hole, this displays the context+   and the expected type.++- ``\e`` prompts for an expression to evaluate.++- ``\r`` reloads and type checks the buffer.++Corresponding commands are also available in the Emacs mode. Support+for other editors can be added in a relatively straightforward manner+by using ``idris –client``.
+ docs/tutorial/interfaces.rst view
@@ -0,0 +1,579 @@+.. _sect-interfaces:++**********+Interfaces+**********++We often want to define functions which work across several different+data types. For example, we would like arithmetic operators to work on+``Int``, ``Integer`` and ``Double`` at the very least. We would like+``==`` to work on the majority of data types. We would like to be able+to display different types in a uniform way.++To achieve this, we use *interfaces*, which are similar to type classes in+Haskell or traits in Rust.  To define an interface, we provide a collection of+overloadable functions.  A simple example is the ``Show``+interface, which is defined in the prelude and provides an interface for+converting values to ``String``:++.. code-block:: idris++    interface Show a where+        show : a -> String++This generates a function of the following type (which we call a+*method* of the ``Show`` interface):++.. code-block:: idris++    show : Show a => a -> String++We can read this as: “under the constraint that ``a`` has an implementation+of ``Show``, take an input ``a`` and return a ``String``.” An implementation+of an interface is defined by giving definitions of the methods of the interface.+For example, the+``Show`` implementation for ``Nat`` could be defined as:++.. code-block:: idris++    Show Nat where+        show Z = "Z"+        show (S k) = "s" ++ show k++::++    Idris> show (S (S (S Z)))+    "sssZ" : String++Only one implementation of an interface can be given for a type — implementations may+not overlap. Implementation declarations can themselves have constraints.+To help with resolution, the arguments of an implementation must be+constructors (either data or type constructors), variables or+constants (i.e. you cannot give an implementation for a function).  For+example, to define a ``Show`` implementation for vectors, we need to know+that there is a ``Show`` implementation for the element type, because we are+going to use it to convert each element to a ``String``:++.. code-block:: idris++    Show a => Show (Vect n a) where+        show xs = "[" ++ show' xs ++ "]" where+            show' : Vect n a -> String+            show' Nil        = ""+            show' (x :: Nil) = show x+            show' (x :: xs)  = show x ++ ", " ++ show' xs++Default Definitions+===================++The library defines an ``Eq`` interface which provides methods for+comparing values for equality or inequality, with implementations for all of+the built-in types:++.. code-block:: idris++    interface Eq a where+        (==) : a -> a -> Bool+        (/=) : a -> a -> Bool++To declare an implementation for a type, we have to give definitions of all+of the methods. For example, for an implementation of ``Eq`` for ``Nat``:++.. code-block:: idris++    Eq Nat where+        Z     == Z     = True+        (S x) == (S y) = x == y+        Z     == (S y) = False+        (S x) == Z     = False++        x /= y = not (x == y)++It is hard to imagine many cases where the ``/=`` method will be+anything other than the negation of the result of applying the ``==``+method. It is therefore convenient to give a default definition for+each method in the interface declaration, in terms of the other method:++.. code-block:: idris++    interface Eq a where+        (==) : a -> a -> Bool+        (/=) : a -> a -> Bool++        x /= y = not (x == y)+        x == y = not (x /= y)++A minimal complete implementation of ``Eq`` requires either+``==`` or ``/=`` to be defined, but does not require both. If a method+definition is missing, and there is a default definition for it, then+the default is used instead.++Extending Interfaces+====================++Interfaces can also be extended. A logical next step from an equality+relation ``Eq`` is to define an ordering relation ``Ord``. We can+define an ``Ord`` interface which inherits methods from ``Eq`` as well as+defining some of its own:++.. code-block:: idris++    data Ordering = LT | EQ | GT++.. code-block:: idris++    interface Eq a => Ord a where+        compare : a -> a -> Ordering++        (<) : a -> a -> Bool+        (>) : a -> a -> Bool+        (<=) : a -> a -> Bool+        (>=) : a -> a -> Bool+        max : a -> a -> a+        min : a -> a -> a++The ``Ord`` interface allows us to compare two values and determine their+ordering. Only the ``compare`` method is required; every other method+has a default definition. Using this we can write functions such as+``sort``, a function which sorts a list into increasing order,+provided that the element type of the list is in the ``Ord`` interface. We+give the constraints on the type variables left of the fat arrow+``=>``, and the function type to the right of the fat arrow:++.. code-block:: idris++    sort : Ord a => List a -> List a++Functions, interfaces and implementations can have multiple+constraints. Multiple constraints are written in brackets in a comma+separated list, for example:++.. code-block:: idris++    sortAndShow : (Ord a, Show a) => List a -> String+    sortAndShow xs = show (sort xs)++Functors and Applicatives+=========================++So far, we have seen single parameter interfaces, where the parameter+is of type ``Type``. In general, there can be any number of parameters+(even zero), and the parameters can have *any* type. If the type+of the parameter is not ``Type``, we need to give an explicit type+declaration. For example, the ``Functor`` interface is defined in the+prelude:++.. code-block:: idris++    interface Functor (f : Type -> Type) where+        map : (m : a -> b) -> f a -> f b++A functor allows a function to be applied across a structure, for+example to apply a function to every element in a ``List``:++.. code-block:: idris++    Functor List where+      map f []      = []+      map f (x::xs) = f x :: map f xs++::++    Idris> map (*2) [1..10]+    [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] : List Integer++Having defined ``Functor``, we can define ``Applicative`` which+abstracts the notion of function application:++.. code-block:: idris++    infixl 2 <*>++    interface Functor f => Applicative (f : Type -> Type) where+        pure  : a -> f a+        (<*>) : f (a -> b) -> f a -> f b++Monads and ``do``-notation+==========================++The ``Monad`` interface allows us to encapsulate binding and computation,+and is the basis of ``do``-notation introduced in Section+:ref:`sect-do`. It extends ``Applicative`` as defined above, and is+defined as follows:++.. code-block:: idris++    interface Applicative m => Monad (m : Type -> Type) where+        (>>=)  : m a -> (a -> m b) -> m b++Inside a ``do`` block, the following syntactic transformations are+applied:++- ``x <- v; e`` becomes ``v >>= (\x => e)``++- ``v; e`` becomes ``v >>= (\_ => e)``++- ``let x = v; e`` becomes ``let x = v in e``++``IO`` has an implementation of ``Monad``, defined using primitive functions.+We can also define an implementation for ``Maybe``, as follows:++.. code-block:: idris++    Monad Maybe where+        Nothing  >>= k = Nothing+        (Just x) >>= k = k x++Using this we can, for example, define a function which adds two+``Maybe Int``, using the monad to encapsulate the error handling:++.. code-block:: idris++    m_add : Maybe Int -> Maybe Int -> Maybe Int+    m_add x y = do x' <- x -- Extract value from x+                   y' <- y -- Extract value from y+                   return (x' + y') -- Add them++This function will extract the values from ``x`` and ``y``, if they+are both available, or return ``Nothing`` if one or both are not ("fail fast"). Managing the+``Nothing`` cases is achieved by the ``>>=`` operator, hidden by the+``do`` notation.++::++    *ifaces> m_add (Just 20) (Just 22)+    Just 42 : Maybe Int+    *ifaces> m_add (Just 20) Nothing+    Nothing : Maybe Int++Pattern Matching Bind+---------------------++Sometimes we want to pattern match immediately on the result of a function+in ``do`` notation. For example, let's say we have a function ``readNumber``+which reads a number from the console, returning a value of the form+``Just x`` if the number is valid, or ``Nothing`` otherwise:++.. code-block:: idris++    readNumber : IO (Maybe Nat)+    readNumber = do+      input <- getLine+      if all isDigit (unpack input)+         then pure (Just (cast input))+         else pure Nothing++If we then use it to write a function to read two numbers, returning+``Nothing`` if neither are valid, then we would like to pattern match+on the result of ``readNumber``:++.. code-block:: idris++    readNumbers : IO (Maybe (Nat, Nat))+    readNumbers = +      do x <- readNumber+         case x of+              Nothing => pure Nothing+              Just x_ok => do y <- readNumber+                              case y of+                                   Nothing => pure Nothing+                                   Just y_ok => pure (Just (x_ok, y_ok))++If there's a lot of error handling, this could get deeply nested very quickly!+So instead, we can combine the bind and the pattern match in one line. For example,+we could try pattern matching on values of the form ``Just x_ok``:++.. code-block:: idris++    readNumbers : IO (Maybe (Nat, Nat))+    readNumbers = +      do Just x_ok <- readNumber+         Just y_ok <- readNumber+         pure (Just (x_ok, y_ok))++There is still a problem, however, because we've now omitted the case for+``Nothing`` so ``readNumbers`` is no longer total! We can add the ``Nothing``+case back as follows:++.. code-block:: idris++    readNumbers : IO (Maybe (Nat, Nat))+    readNumbers = +      do Just x_ok <- readNumber | Nothing => pure Nothing+         Just y_ok <- readNumber | Nothing => pure Nothing+         pure (Just (x_ok, y_ok))++The effect of this version of ``readNumbers`` is identical to the first (in+fact, it is syntactic sugar for it and directly translated back into that form).+The first part of each statement (``Just x_ok <-`` and ``Just y_ok <-``) gives+the preferred binding - if this matches, execution will continue with the rest+of the ``do`` block. The second part gives the alternative bindings, of which+there may be more than one.++``!``-notation+--------------++In many cases, using ``do``-notation can make programs unnecessarily+verbose, particularly in cases such as ``m_add`` above where the value+bound is used once, immediately. In these cases, we can use a+shorthand version, as follows:++.. code-block:: idris++    m_add : Maybe Int -> Maybe Int -> Maybe Int+    m_add x y = return (!x + !y)++The notation ``!expr`` means that the expression ``expr`` should be+evaluated and then implicitly bound. Conceptually, we can think of+``!`` as being a prefix function with the following type:++.. code-block:: idris++    (!) : m a -> a++Note, however, that it is not really a function, merely syntax! In+practice, a subexpression ``!expr`` will lift ``expr`` as high as+possible within its current scope, bind it to a fresh name ``x``, and+replace ``!expr`` with ``x``. Expressions are lifted depth first, left+to right. In practice, ``!``-notation allows us to program in a more+direct style, while still giving a notational clue as to which+expressions are monadic.++For example, the expression:++.. code-block:: idris++    let y = 42 in f !(g !(print y) !x)++is lifted to:++.. code-block:: idris++    let y = 42 in do y' <- print y+                     x' <- x+                     g' <- g y' x'+                     f g'++Monad comprehensions+--------------------++The list comprehension notation we saw in Section+:ref:`sect-more-expr` is more general, and applies to anything which+has an implementation of both ``Monad`` and ``Alternative``:++.. code-block:: idris++    interface Applicative f => Alternative (f : Type -> Type) where+        empty : f a+        (<|>) : f a -> f a -> f a++In general, a comprehension takes the form ``[ exp | qual1, qual2, …,+qualn ]`` where ``quali`` can be one of:++- A generator ``x <- e``++- A *guard*, which is an expression of type ``Bool``++- A let binding ``let x = e``++To translate a comprehension ``[exp | qual1, qual2, …, qualn]``, first+any qualifier ``qual`` which is a *guard* is translated to ``guard+qual``, using the following function:++.. code-block:: idris++    guard : Alternative f => Bool -> f ()++Then the comprehension is converted to ``do`` notation:++.. code-block:: idris++    do { qual1; qual2; ...; qualn; return exp; }++Using monad comprehensions, an alternative definition for ``m_add``+would be:++.. code-block:: idris++    m_add : Maybe Int -> Maybe Int -> Maybe Int+    m_add x y = [ x' + y' | x' <- x, y' <- y ]++Idiom brackets+==============++While ``do`` notation gives an alternative meaning to sequencing,+idioms give an alternative meaning to *application*. The notation and+larger example in this section is inspired by Conor McBride and Ross+Paterson’s paper “Applicative Programming with Effects” [1]_.++First, let us revisit ``m_add`` above. All it is really doing is+applying an operator to two values extracted from ``Maybe Int``. We+could abstract out the application:++.. code-block:: idris++    m_app : Maybe (a -> b) -> Maybe a -> Maybe b+    m_app (Just f) (Just a) = Just (f a)+    m_app _        _        = Nothing++Using this, we can write an alternative ``m_add`` which uses this+alternative notion of function application, with explicit calls to+``m_app``:++.. code-block:: idris++    m_add' : Maybe Int -> Maybe Int -> Maybe Int+    m_add' x y = m_app (m_app (Just (+)) x) y++Rather than having to insert ``m_app`` everywhere there is an+application, we can use idiom brackets to do the job for us.+To do this, we can give ``Maybe`` an implementation of ``Applicative``+as follows, where ``<*>`` is defined in the same way as ``m_app``+above (this is defined in the Idris library):++.. code-block:: idris++    Applicative Maybe where+        pure = Just++        (Just f) <*> (Just a) = Just (f a)+        _        <*> _        = Nothing++Using ``<*>`` we can use this implementation as follows, where a function+application ``[| f a1 …an |]`` is translated into ``pure f <*> a1 <*>+… <*> an``:++.. code-block:: idris++    m_add' : Maybe Int -> Maybe Int -> Maybe Int+    m_add' x y = [| x + y |]++An error-handling interpreter+-----------------------------++Idiom notation is commonly useful when defining evaluators. McBride+and Paterson describe such an evaluator [1]_, for a language similar+to the following:++.. code-block:: idris++    data Expr = Var String      -- variables+              | Val Int         -- values+              | Add Expr Expr   -- addition++Evaluation will take place relative to a context mapping variables+(represented as ``String``\s) to ``Int`` values, and can possibly fail.+We define a data type ``Eval`` to wrap an evaluator:++.. code-block:: idris++    data Eval : Type -> Type where+         MkEval : (List (String, Int) -> Maybe a) -> Eval a++Wrapping the evaluator in a data type means we will be able to provide+implementations of interfaces for it later. We begin by defining a function to+retrieve values from the context during evaluation:++.. code-block:: idris++    fetch : String -> Eval Int+    fetch x = MkEval (\e => fetchVal e) where+        fetchVal : List (String, Int) -> Maybe Int+        fetchVal [] = Nothing+        fetchVal ((v, val) :: xs) = if (x == v)+                                      then (Just val)+                                      else (fetchVal xs)++When defining an evaluator for the language, we will be applying functions in+the context of an ``Eval``, so it is natural to give ``Eval`` an implementation+of ``Applicative``. Before ``Eval`` can have an implementation of+``Applicative`` it is necessary for ``Eval`` to have an implementation of+``Functor``:++.. code-block:: idris++    Functor Eval where+        map f (MkEval g) = MkEval (\e => map f (g e))++    Applicative Eval where+        pure x = MkEval (\e => Just x)++        (<*>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where+            app : Maybe (a -> b) -> Maybe a -> Maybe b+            app (Just fx) (Just gx) = Just (fx gx)+            app _         _         = Nothing++Evaluating an expression can now make use of the idiomatic application+to handle errors:++.. code-block:: idris++    eval : Expr -> Eval Int+    eval (Var x)   = fetch x+    eval (Val x)   = [| x |]+    eval (Add x y) = [| eval x + eval y |]++    runEval : List (String, Int) -> Expr -> Maybe Int+    runEval env e = case eval e of+        MkEval envFn => envFn env++Named Implementations+=====================++It can be desirable to have multiple implementations of an interface for the+same type, for example to provide alternative methods for sorting or printing+values.  To achieve this, implementations can be *named* as follows:++.. code-block:: idris++    [myord] Ord Nat where+       compare Z (S n)     = GT+       compare (S n) Z     = LT+       compare Z Z         = EQ+       compare (S x) (S y) = compare @{myord} x y++This declares an implementation as normal, but with an explicit name,+``myord``. The syntax ``compare @{myord}`` gives an explicit implementation to+``compare``, otherwise it would use the default implementation for ``Nat``. We+can use this, for example, to sort a list of ``Nat`` in reverse.+Given the following list:++.. code-block:: idris++    testList : List Nat+    testList = [3,4,1]++We can sort it using the default ``Ord`` implementation, then the named+implementation ``myord`` as follows, at the Idris prompt:++::++    *named_impl> show (sort testList)+    "[sO, sssO, ssssO]" : String+    *named_impl> show (sort @{myord} testList)+    "[ssssO, sssO, sO]" : String+++Determining Parameters+======================++When an interface has more than one parameter, it can help resolution if the+parameters used to find an implementation are restricted. For example:++.. code-block:: idris++    interface Monad m => MonadState s (m : Type -> Type) | m where+      get : m s+      put : s -> m ()++In this interface, only ``m`` needs to be known to find an implementation of+this interface, and ``s`` can then be determined from the implementation. This+is declared with the ``| m`` after the interface declaration. We call ``m`` a+*determining parameter* of the ``MonadState`` interface, because it is the+parameter used to find an implementation.+++.. [1] Conor McBride and Ross Paterson. 2008. Applicative programming+       with effects. J. Funct. Program. 18, 1 (January 2008),+       1-13. DOI=10.1017/S0956796807006326+       http://dx.doi.org/10.1017/S0956796807006326
+ docs/tutorial/interp.rst view
@@ -0,0 +1,300 @@+.. _sect-interp:++***********************************+Example: The Well-Typed Interpreter+***********************************++In this section, we’ll use the features we’ve seen so far to write a+larger example, an interpreter for a simple functional programming+language, with variables, function application, binary operators and+an ``if...then...else`` construct. We will use the dependent type+system to ensure that any programs which can be represented are+well-typed.++Representing Languages+======================++First, let us define the types in the language. We have integers,+booleans, and functions, represented by ``Ty``:++.. code-block:: idris++    data Ty = TyInt | TyBool | TyFun Ty Ty++We can write a function to translate these representations to a concrete+Idris type — remember that types are first class, so can be+calculated just like any other value:++.. code-block:: idris++    interpTy : Ty -> Type+    interpTy TyInt       = Integer+    interpTy TyBool      = Bool+    interpTy (TyFun A T) = interpTy A -> interpTy T++We're going to define a representation of our language in such a way+that only well-typed programs can be represented. We'll index the+representations of expressions by their type, **and** the types of+local variables (the context). The context can be represented using+the ``Vect`` data type, and as it will be used regularly it will be+represented as an implicit argument. To do so we define everything in+a ``using`` block (keep in mind that everything after this point needs+to be indented so as to be inside the ``using`` block):++.. code-block:: idris++    using (G:Vect n Ty)++Expressions are indexed by the types of the local variables, and the type of+the expression itself:++.. code-block:: idris++    data Expr : Vect n Ty -> Ty -> Type++The full representation of expressions is:++.. code-block:: idris++    data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where+        Stop : HasType FZ (t :: G) t+        Pop  : HasType k G t -> HasType (FS k) (u :: G) t++    data Expr : Vect n Ty -> Ty -> Type where+        Var : HasType i G t -> Expr G t+        Val : (x : Integer) -> Expr G TyInt+        Lam : Expr (a :: G) t -> Expr G (TyFun a t)+        App : Expr G (TyFun a t) -> Expr G a -> Expr G t+        Op  : (interpTy a -> interpTy b -> interpTy c) ->+              Expr G a -> Expr G b -> Expr G c+        If  : Expr G TyBool ->+              Lazy (Expr G a) ->+              Lazy (Expr G a) -> Expr G a++The code above makes use of the ``Vect`` and ``Fin`` types from the+Idris standard library. We import them because they are not provided+in the prelude:++.. code-block:: idris++    import Data.Vect+    import Data.Fin++Since expressions are indexed by their type, we can read the typing+rules of the language from the definitions of the constructors. Let us+look at each constructor in turn.++We use a nameless representation for variables — they are *de Bruijn+indexed*. Variables are represented by a proof of their membership in+the context, ``HasType i G T``, which is a proof that variable ``i``+in context ``G`` has type ``T``. This is defined as follows:++.. code-block:: idris++    data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where+        Stop : HasType FZ (t :: G) t+        Pop  : HasType k G t -> HasType (FS k) (u :: G) t++We can treat *Stop* as a proof that the most recently defined variable+is well-typed, and *Pop n* as a proof that, if the ``n``\ th most+recently defined variable is well-typed, so is the ``n+1``\ th. In+practice, this means we use ``Stop`` to refer to the most recently+defined variable, ``Pop Stop`` to refer to the next, and so on, via+the ``Var`` constructor:++.. code-block:: idris++    Var : HasType i G t -> Expr G t++So, in an expression ``\x,\y. x y``, the variable ``x`` would have a+de Bruijn index of 1, represented as ``Pop Stop``, and ``y 0``,+represented as ``Stop``. We find these by counting the number of+lambdas between the definition and the use.++A value carries a concrete representation of an integer:++.. code-block:: idris++    Val : (x : Integer) -> Expr G TyInt++A lambda creates a function. In the scope of a function of type ``a ->+t``, there is a new local variable of type ``a``, which is expressed+by the context index:++.. code-block:: idris++    Lam : Expr (a :: G) t -> Expr G (TyFun a t)++Function application produces a value of type ``t`` given a function+from ``a`` to ``t`` and a value of type ``a``:++.. code-block:: idris++    App : Expr G (TyFun a t) -> Expr G a -> Expr G t++We allow arbitrary binary operators, where the type of the operator+informs what the types of the arguments must be:++.. code-block:: idris++    Op : (interpTy a -> interpTy b -> interpTy c) ->+         Expr G a -> Expr G b -> Expr G c++Finally, ``If`` expressions make a choice given a boolean. Each branch+must have the same type, and we will evaluate the branches lazily so+that only the branch which is taken need be evaluated:++.. code-block:: idris++    If : Expr G TyBool ->+         Lazy (Expr G a) ->+         Lazy (Expr G a) ->+         Expr G a++Writing the Interpreter+=======================++When we evaluate an ``Expr``, we'll need to know the values in scope,+as well as their types. ``Env`` is an environment, indexed over the+types in scope. Since an environment is just another form of list,+albeit with a strongly specified connection to the vector of local+variable types, we use the usual ``::`` and ``Nil`` constructors so+that we can use the usual list syntax. Given a proof that a variable+is defined in the context, we can then produce a value from the+environment:++.. code-block:: idris++    data Env : Vect n Ty -> Type where+        Nil  : Env Nil+        (::) : interpTy a -> Env G -> Env (a :: G)++    lookup : HasType i G t -> Env G -> interpTy t+    lookup Stop    (x :: xs) = x+    lookup (Pop k) (x :: xs) = lookup k xs++Given this, an interpreter is a function which+translates an ``Expr`` into a concrete Idris value with respect to a+specific environment:++.. code-block:: idris++    interp : Env G -> Expr G t -> interpTy t++The complete interpreter is defined as follows, for reference. For+each constructor, we translate it into the corresponding Idris value:++.. code-block:: idris++    interp env (Var i)     = lookup i env+    interp env (Val x)     = x+    interp env (Lam sc)    = \x => interp (x :: env) sc+    interp env (App f s)   = interp env f (interp env s)+    interp env (Op op x y) = op (interp env x) (interp env y)+    interp env (If x t e)  = if interp env x then interp env t+                                             else interp env e++Let us look at each case in turn.  To translate a variable, we simply look it+up in the environment:++.. code-block:: idris++    interp env (Var i) = lookup i env++To translate a value, we just return the concrete representation of the+value:++.. code-block:: idris++    interp env (Val x) = x++Lambdas are more interesting. In this case, we construct a function+which interprets the scope of the lambda with a new value in the+environment. So, a function in the object language is translated to an+Idris function:++.. code-block:: idris++    interp env (Lam sc) = \x => interp (x :: env) sc++For an application, we interpret the function and its argument and apply+it directly. We know that interpreting ``f`` must produce a function,+because of its type:++.. code-block:: idris++    interp env (App f s) = interp env f (interp env s)++Operators and conditionals are, again, direct translations into the+equivalent Idris constructs. For operators, we apply the function to+its operands directly, and for ``If``, we apply the Idris+``if...then...else`` construct directly.++.. code-block:: idris++    interp env (Op op x y) = op (interp env x) (interp env y)+    interp env (If x t e)  = if interp env x then interp env t+                                             else interp env e++Testing+=======++We can make some simple test functions. Firstly, adding two inputs+``\x. \y. y + x`` is written as follows:++.. code-block:: idris++    add : Expr G (TyFun TyInt (TyFun TyInt TyInt))+    add = Lam (Lam (Op (+) (Var Stop) (Var (Pop Stop))))++More interestingly, a factorial function ``fact``+(e.g. ``\x. if (x == 0) then 1 else (fact (x-1) * x)``),+can be written as:++.. code-block:: idris++    fact : Expr G (TyFun TyInt TyInt)+    fact = Lam (If (Op (==) (Var Stop) (Val 0))+                   (Val 1)+                   (Op (*) (App fact (Op (-) (Var Stop) (Val 1)))+                           (Var Stop)))++Running+=======++To finish, we write a ``main`` program which interprets the factorial+function on user input:++.. code-block:: idris++    main : IO ()+    main = do putStr "Enter a number: "+              x <- getLine+              printLn (interp [] fact (cast x))++Here, ``cast`` is an overloaded function which converts a value from+one type to another if possible. Here, it converts a string to an+integer, giving 0 if the input is invalid. An example run of this+program at the Idris interactive environment is:+++.. _factrun:+.. literalinclude:: ../listing/idris-prompt-interp.txt+++Aside: ``cast``+---------------++The prelude defines an interface ``Cast`` which allows conversion+between types:++.. code-block:: idris++    interface Cast from to where+        cast : from -> to++It is a *multi-parameter* interface, defining the source type and+object type of the cast. It must be possible for the type checker to+infer *both* parameters at the point where the cast is applied. There+are casts defined between all of the primitive types, as far as they+make sense.
+ docs/tutorial/introduction.rst view
@@ -0,0 +1,69 @@+.. _sect-intro:++************+Introduction+************++In conventional programming languages, there is a clear distinction+between *types* and *values*. For example, in `Haskell+<http://www.haskell.org>`_, the following are types, representing+integers, characters, lists of characters, and lists of any value+respectively:++-  ``Int``, ``Char``, ``[Char]``, ``[a]``++Correspondingly, the following values are examples of inhabitants of+those types:++-  ``42``, ``’a’``, ``"Hello world!"``, ``[2,3,4,5,6]``++In a language with *dependent types*, however, the distinction is less+clear. Dependent types allow types to “depend” on values — in other+words, types are a *first class* language construct and can be+manipulated like any other value. The standard example is the type of+lists of a given length [1]_, ``Vect n a``, where ``a`` is the element+type and ``n`` is the length of the list and can be an arbitrary term.++When types can contain values, and where those values describe+properties, for example the length of a list, the type of a function+can begin to describe its own properties. Take for example the+concatenation of two lists. This operation has the property that the+resulting list's length is the sum of the lengths of the two input+lists. We can therefore give the following type to the ``app``+function, which concatenates vectors:++.. code-block:: idris++    app : Vect n a -> Vect m a -> Vect (n + m) a++This tutorial introduces Idris, a general purpose functional+programming language with dependent types. The goal of the Idris+project is to build a dependently typed language suitable for+verifiable general purpose programming. To this end, Idris is a compiled+language which aims to generate efficient executable code. It also has+a lightweight foreign function interface which allows easy interaction+with external ``C`` libraries.++Intended Audience+=================++This tutorial is intended as a brief introduction to the language, and+is aimed at readers already familiar with a functional language such+as `Haskell <http://www.haskell.org>`_ or `OCaml <http://ocaml.org>`_.+In particular, a certain amount of familiarity with Haskell syntax is+assumed, although most concepts will at least be explained+briefly. The reader is also assumed to have some interest in using+dependent types for writing and verifying systems software.++Example Code+============++This tutorial includes some example code, which has been tested with+against Idris. These files are available with the Idris distribution,+so that you can try them out easily. They can be found under+``samples``. It is, however, strongly recommended that you type+them in yourself, rather than simply loading and reading them.++.. [1]+   Typically, and perhaps confusingly, referred to in the dependently+   typed programming literature as “vectors”
+ docs/tutorial/miscellany.rst view
@@ -0,0 +1,555 @@+.. _sect-misc:++**********+Miscellany+**********++In this section we discuss a variety of additional features:+++ auto, implicit, and default arguments;++ literate programming;++ interfacing with external libraries through the foreign function++ interface;++ type providers;++ code generation; and++ the universe hierarchy.++Auto implicit arguments+=======================++We have already seen implicit arguments, which allows arguments to be+omitted when they can be inferred by the type checker, e.g.++.. code-block:: idris++    index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a++In other situations, it may be possible to infer arguments not by type+checking but by searching the context for an appropriate value, or+constructing a proof. For example, the following definition of ``head``+which requires a proof that the list is non-empty:++.. code-block:: idris++    isCons : List a -> Bool+    isCons [] = False+    isCons (x :: xs) = True++    head : (xs : List a) -> (isCons xs = True) -> a+    head (x :: xs) _ = x++If the list is statically known to be non-empty, either because its+value is known or because a proof already exists in the context, the+proof can be constructed automatically. Auto implicit arguments allow+this to happen silently. We define ``head`` as follows:++.. code-block:: idris++    head : (xs : List a) -> {auto p : isCons xs = True} -> a+    head (x :: xs) = x++The ``auto`` annotation on the implicit argument means that Idris+will attempt to fill in the implicit argument by searching for a value+of the appropriate type. It will try the following, in order:++- Local variables, i.e. names bound in pattern matches or ``let`` bindings,+  with exactly the right type.+- The constructors of the required type. If they have arguments, it will+  search recursively up to a maximum depth of 100.+- Local variables with function types, searching recursively for the+  arguments.+- Any function with the appropriate return type which is marked with the+  ``%hint`` annotation.++In the case that a proof is not found, it can be provided explicitly as normal:++.. code-block:: idris++    head xs {p = ?headProof}++More generally, we can fill in implicit arguments with a default value+by annotating them with ``default``. The definition above is equivalent+to:++.. code-block:: idris++    head : (xs : List a) ->+           {default proof { trivial; } p : isCons xs = True} -> a+    head (x :: xs) = x++Implicit conversions+====================++Idris supports the creation of *implicit conversions*, which allow+automatic conversion of values from one type to another when required to+make a term type correct. This is intended to increase convenience and+reduce verbosity. A contrived but simple example is the following:++.. code-block:: idris++    implicit intString : Int -> String+    intString = show++    test : Int -> String+    test x = "Number " ++ x++In general, we cannot append an ``Int`` to a ``String``, but the+implicit conversion function ``intString`` can convert ``x`` to a+``String``, so the definition of ``test`` is type correct. An implicit+conversion is implemented just like any other function, but given the+``implicit`` modifier, and restricted to one explicit argument.++Only one implicit conversion will be applied at a time. That is,+implicit conversions cannot be chained. Implicit conversions of simple+types, as above, are however discouraged! More commonly, an implicit+conversion would be used to reduce verbosity in an embedded domain+specific language, or to hide details of a proof. Such examples are+beyond the scope of this tutorial.++Literate programming+====================++Like Haskell, Idris supports *literate* programming. If a file has+an extension of ``.lidr`` then it is assumed to be a literate file. In+literate programs, everything is assumed to be a comment unless the line+begins with a greater than sign ``>``, for example:++.. code-block:: idris++    > module literate++    This is a comment. The main program is below++    > main : IO ()+    > main = putStrLn "Hello literate world!\n"++An additional restriction is that there must be a blank line between a+program line (beginning with ``>``) and a comment line (beginning with+any other character).++Foreign function calls+======================++For practical programming, it is often necessary to be able to use+external libraries, particularly for interfacing with the operating+system, file system, networking, *et cetera*. Idris provides a+lightweight foreign function interface for achieving this, as part of+the prelude. For this, we assume a certain amount of knowledge of C and+the ``gcc`` compiler. First, we define a datatype which describes the+external types we can handle:++.. code-block:: idris++    data FTy = FInt | FFloat | FChar | FString | FPtr | FUnit++Each of these corresponds directly to a C type. Respectively: ``int``,+``double``, ``char``, ``char*``, ``void*`` and ``void``. There is also a+translation to a concrete Idris type, described by the following+function:++.. code-block:: idris++    interpFTy : FTy -> Type+    interpFTy FInt    = Int+    interpFTy FFloat  = Double+    interpFTy FChar   = Char+    interpFTy FString = String+    interpFTy FPtr    = Ptr+    interpFTy FUnit   = ()++A foreign function is described by a list of input types and a return+type, which can then be converted to an Idris type:++.. code-block:: idris++    ForeignTy : (xs:List FTy) -> (t:FTy) -> Type++A foreign function is assumed to be impure, so ``ForeignTy`` builds an+``IO`` type, for example:++.. code-block:: idris++    Idris> ForeignTy [FInt, FString] FString+    Int -> String -> IO String : Type++    Idris> ForeignTy [FInt, FString] FUnit+    Int -> String -> IO () : Type++We build a call to a foreign function by giving the name of the+function, a list of argument types and the return type. The built in+construct ``mkForeign`` converts this description to a function callable+by Idris:++.. code-block:: idris++    data Foreign : Type -> Type where+        FFun : String -> (xs:List FTy) -> (t:FTy) ->+               Foreign (ForeignTy xs t)++    mkForeign : Foreign x -> x++Note that the compiler expects ``mkForeign`` to be fully applied to+build a complete foreign function call. For example, the ``putStr``+function is implemented as follows, as a call to an external function+``putStr`` defined in the run-time system:++.. code-block:: idris++    putStr : String -> IO ()+    putStr x = mkForeign (FFun "putStr" [FString] FUnit) x++Include and linker directives+-----------------------------++Foreign function calls are translated directly to calls to C functions,+with appropriate conversion between the Idris representation of a+value and the C representation. Often this will require extra libraries+to be linked in, or extra header and object files. This is made possible+through the following directives:++-  ``%lib target x`` — include the ``libx`` library. If the target is+   ``C`` this is equivalent to passing the ``-lx`` option to ``gcc``. If+   the target is Java the library will be interpreted as a+   ``groupId:artifactId:packaging:version`` dependency coordinate for+   maven.++-  ``%include target x`` — use the header file or import ``x`` for the+   given back end target.++-  ``%link target x.o`` — link with the object file ``x.o`` when using+   the given back end target.++-  ``%dynamic x.so`` — dynamically link the interpreter with the shared+   object ``x.so``.++Testing foreign function calls+------------------------------++Normally, the Idris interpreter (used for typechecking and at the REPL)+will not perform IO actions. Additionally, as it neither generates C+code nor compiles to machine code, the ``%lib``, ``%include`` and+``%link`` directives have no effect. IO actions and FFI calls can be+tested using the special REPL command ``:x EXPR``, and C libraries can+be dynamically loaded in the interpreter by using the ``:dynamic``+command or the ``%dynamic`` directive. For example:++.. code-block:: idris++    Idris> :dynamic libm.so+    Idris> :x unsafePerformIO ((mkForeign (FFun "sin" [FFloat] FFloat)) 1.6)+    0.9995736030415051 : Double++Type Providers+==============++Idris type providers, inspired by F#’s type providers, are a means of+making our types be “about” something in the world outside of Idris. For+example, given a type that represents a database schema and a query that+is checked against it, a type provider could read the schema of a real+database during type checking.++Idris type providers use the ordinary execution semantics of Idris to+run an IO action and extract the result. This result is then saved as a+constant in the compiled code. It can be a type, in which case it is+used like any other type, or it can be a value, in which case it can be+used as any other value, including as an index in types.++Type providers are still an experimental extension. To enable the+extension, use the ``%language`` directive:++.. code-block:: idris++    %language TypeProviders++A provider ``p`` for some type ``t`` is simply an expression of type+``IO (Provider t)``. The ``%provide`` directive causes the type checker+to execute the action and bind the result to a name. This is perhaps+best illustrated with a simple example. The type provider ``fromFile``+reads a text file. If the file consists of the string ``Int``, then the+type ``Int`` will be provided. Otherwise, it will provide the type+``Nat``.++.. code-block:: idris++    strToType : String -> Type+    strToType "Int" = Int+    strToType _ = Nat++    fromFile : String -> IO (Provider Type)+    fromFile fname = do Right str <- readFile fname+		          | Left err => pure (Provide Void)+		        pure (Provide (strToType (trim str)))++We then use the ``%provide`` directive:++.. code-block:: idris++    %provide (T1 : Type) with fromFile "theType"++    foo : T1+    foo = 2++If the file named ``theType`` consists of the word ``Int``, then ``foo``+will be an ``Int``. Otherwise, it will be a ``Nat``. When Idris+encounters the directive, it first checks that the provider expression+``fromFile theType`` has type ``IO (Provider Type)``. Next, it executes+the provider. If the result is ``Provide t``, then ``T1`` is defined as+``t``. Otherwise, the result is an error.++Our datatype ``Provider t`` has the following definition:++.. code-block:: idris++    data Provider a = Error String+                    | Provide a++We have already seen the ``Provide`` constructor. The ``Error``+constructor allows type providers to return useful error messages. The+example in this section was purposefully simple. More complex type+provider implementations, including a statically-checked SQLite binding,+are available in an external collection [1]_.++C Target+========++The default target of Idris is C. Compiling via :++::++    $ idris hello.idr -o hello++is equivalent to :++::++    $ idris --codegen C hello.idr -o hello++When the command above is used, a temporary C source is generated, which+is then compiled into an executable named ``hello``.++In order to view the generated C code, compile via :++::++    $ idris hello.idr -S -o hello.c++To turn optimisations on, use the ``%flag C`` pragma within the code, as+is shown below :++.. code-block:: idris++    module Main+    %flag C "-O3"++    factorial : Int -> Int+    factorial 0 = 1+    factorial n = n * (factorial (n-1))++    main : IO ()+    main = do+         putStrLn $ show $ factorial 3++JavaScript Target+=================++Idris is capable of producing *JavaScript* code that can be run in a+browser as well as in the *NodeJS* environment or alike. One can use the+FFI to communicate with the *JavaScript* ecosystem.++Code Generation+---------------++Code generation is split into two separate targets. To generate code+that is tailored for running in the browser issue the following command:++::++    $ idris --codegen javascript hello.idr -o hello.js++The resulting file can be embedded into your HTML just like any other+*JavaScript* code.++Generating code for *NodeJS* is slightly different. Idris outputs a+*JavaScript* file that can be directly executed via ``node``.++::++    $ idris --codegen node hello.idr -o hello+    $ ./hello+    Hello world++Take into consideration that the *JavaScript* code generator is using+``console.log`` to write text to ``stdout``, this means that it will+automatically add a newline to the end of each string. This behaviour+does not show up in the *NodeJS* code generator.++Using the FFI+-------------++To write a useful application we need to communicate with the outside+world. Maybe we want to manipulate the DOM or send an Ajax request. For+this task we can use the FFI. Since most *JavaScript* APIs demand+callbacks we need to extend the FFI so we can pass functions as+arguments.++The *JavaScript* FFI works a little bit differently than the regular+FFI. It uses positional arguments to directly insert our arguments into+a piece of *JavaScript* code.++One could use the primitive addition of *JavaScript* like so:++.. code-block:: idris++    module Main++    primPlus : Int -> Int -> IO Int+    primPlus a b = mkForeign (FFun "%0 + %1" [FInt, FInt] FInt) a b++    main : IO ()+    main = do+      a <- primPlus 1 1+      b <- primPlus 1 2+      print (a, b)++Notice that the ``%n`` notation qualifies the position of the ``n``-th+argument given to our foreign function starting from 0. When you need a+percent sign rather than a position simply use ``%%`` instead.++Passing functions to a foreign function is very similar. Let’s assume+that we want to call the following function from the *JavaScript* world:++.. code-block:: idris++    function twice(f, x) {+      return f(f(x));+    }++We obviously need to pass a function ``f`` here (we can infer it from+the way we use ``f`` in ``twice``, it would be more obvious if+*JavaScript* had types).++The *JavaScript* FFI is able to understand functions as arguments when+you give it something of type ``FFunction``. The following example code+calls ``twice`` in *JavaScript* and returns the result to our Idris+program:++.. code-block:: idris++    module Main++    twice : (Int -> Int) -> Int -> IO Int+    twice f x = mkForeign (+      FFun "twice(%0,%1)" [FFunction FInt FInt, FInt] FInt+    ) f x++    main : IO ()+    main = do+      a <- twice (+1) 1+      print a++The program outputs ``3``, just like we expected.++Including external *JavaScript* files+-------------------------------------++Whenever one is working with *JavaScript* one might want to include+external libraries or just some functions that she or he wants to call+via FFI which are stored in external files. The *JavaScript* and+*NodeJS* code generators understand the ``%include`` directive. Keep in+mind that *JavaScript* and *NodeJS* are handled as different code+generators, therefore you will have to state which one you want to+target. This means that you can include different files for *JavaScript*+and *NodeJS* in the same Idris source file.++So whenever you want to add an external *JavaScript* file you can do+this like so:++For *NodeJS*:++.. code-block:: idris++      %include Node "path/to/external.js"++And for use in the browser:++.. code-block:: idris++      %include JavaScript "path/to/external.js"++The given files will be added to the top of the generated code.++Including *NodeJS* modules+--------------------------++The *NodeJS* code generator can also include modules with the ``%lib``+directive.++.. code-block:: idris++      %lib Node "fs"++This directive compiles into the following *JavaScript*++.. code-block:: javascript++      var fs = require("fs");++Shrinking down generated *JavaScript*+-------------------------------------++Idris can produce very big chunks of *JavaScript* code. However, the+generated code can be minified using the ``closure-compiler`` from+Google. Any other minifier is also suitable but ``closure-compiler``+offers advanced compilation that does some aggressive inlining and code+elimination. Idris can take full advantage of this compilation mode+and it’s highly recommended to use it when shipping a *JavaScript*+application written in Idris.++Cumulativity+============++Since values can appear in types and *vice versa*, it is natural that+types themselves have types. For example:++::++    *universe> :t Nat+    Nat : Type+    *universe> :t Vect+    Vect : Nat -> Type -> Type++But what about the type of ``Type``? If we ask Idris it reports++::++    *universe> :t Type+    Type : Type 1++If ``Type`` were its own type, it would lead to an inconsistency due to+`Girard’s paradox <http://www.cs.cmu.edu/afs/cs.cmu.edu/user/kw/www/scans/girard72thesis.pdf>`_ , so internally there is a+*hierarchy* of types (or *universes*):++.. code-block:: idris++    Type : Type 1 : Type 2 : Type 3 : ...++Universes are *cumulative*, that is, if ``x : Type n`` we can also have+that ``x : Type m``, as long as ``n < m``. The typechecker generates+such universe constraints and reports an error if any inconsistencies+are found. Ordinarily, a programmer does not need to worry about this,+but it does prevent (contrived) programs such as the following:++.. code-block:: idris++    myid : (a : Type) -> a -> a+    myid _ x = x++    idid :  (a : Type) -> a -> a+    idid = myid _ myid++The application of ``myid`` to itself leads to a cycle in the universe+hierarchy — ``myid``\ ’s first argument is a ``Type``, which cannot be+at a lower level than required if it is applied to itself.++.. [1]+   https://github.com/david-christiansen/idris-type-providers
+ docs/tutorial/modules.rst view
@@ -0,0 +1,301 @@+.. _sect-namespaces:++**********************+Modules and Namespaces+**********************++An Idris program consists of a collection of modules. Each module+includes an optional ``module`` declaration giving the name of the+module, a list of ``import`` statements giving the other modules which+are to be imported, and a collection of declarations and definitions of+types, interfaces and functions. For example, the listing below gives a+module which defines a binary tree type ``BTree`` (in a file+``Btree.idr``):++.. code-block:: idris++    module Btree++    data BTree a = Leaf+                 | Node (BTree a) a (BTree a)++    insert : Ord a => a -> BTree a -> BTree a+    insert x Leaf = Node Leaf x Leaf+    insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)+                                       else (Node l v (insert x r))++    toList : BTree a -> List a+    toList Leaf = []+    toList (Node l v r) = Btree.toList l ++ (v :: Btree.toList r)++    toTree : Ord a => List a -> BTree a+    toTree [] = Leaf+    toTree (x :: xs) = insert x (toTree xs)+++Then, this gives a main program (in a file+``bmain.idr``) which uses the ``Btree`` module to sort a list:++.. code-block:: idris++    module Main++    import Btree++    main : IO ()+    main = do let t = toTree [1,8,2,7,9,3]+              print (Btree.toList t)++++The same names can be defined in multiple modules. This is possible+because in practice names are *qualified* with the name of the module.+The names defined in the ``Btree`` module are, in full:+++ ``Btree.BTree``++ ``Btree.Leaf``++ ``Btree.Node``++ ``Btree.insert``++ ``Btree.toList``++ ``Btree.toTree``++If names are otherwise unambiguous, there is no need to give the fully+qualified name. Names can be disambiguated either by giving an explicit+qualification, or according to their type.++There is no formal link between the module name and its filename,+although it is generally advisable to use the same name for each. An+``import`` statement refers to a filename, using dots to separate+directories. For example, ``import foo.bar`` would import the file+``foo/bar.idr``, which would conventionally have the module declaration+``module foo.bar``. The only requirement for module names is that the+main module, with the ``main`` function, must be called+``Main``—although its filename need not be ``Main.idr``.++Export Modifiers+================++Idris allows for fine-grained control over the visibility of a+module's contents. By default, all names defined in a module are kept+private.  This aides in specification of a minimal interface and for+internal details to be left hidden.  Idris allows for functions,+types, and interfaces to be marked as: ``private``, ``export``, or+``public export``.  Their general meaning is as follows:++- ``private`` meaning that it's not exported at all. This is the+  default.++- ``export`` meaning that its top level type is exported.++- ``public export`` meaning that the entire definition is exported.+++A further restriction in modifying the visibility is that definitions+must not refer to anything within a lower level of visibility. For+example, ``public export`` definitions cannot use private names, and+``export`` types cannot use private names. This is to prevent private+names leaking into a module's interface.++Meaning for Functions+---------------------++- ``export`` the type is exported++- ``public export`` the type and definition are exported, and the+  definition can be used after it is imported. In other words, the+  definition itself is considered part of the module's interface. The+  long name ``public export`` is intended to make you think twice+  about doing this.++.. note::++   Type synonyms in Idris are created by writing a function. When+   setting the visibility for a module, it might be a good idea to+   ``public export`` all type synonyms if they are to be used outside+   the module. Otherwise, Idris won't know what the synonym is a+   synonym for.+++Meaning for Data Types+----------------------++For data types, the meanings are:++- ``export``  the type constructor is exported++- ``public export`` the type constructor and data constructors are+  exported+++Meaning for Interfaces+----------------------++For interfaces, the meanings are:++- ``export`` the interface name is exported+- ``public export`` the interface name, method names and default+  definitions are exported++++``BTree`` Revisited++++++++++++++++++++++For our ``BTree`` module, it makes sense for the tree data type and the+functions to be exported as ``export``, as we see below:++.. code-block:: idris++    module BTree++    export data BTree a = Leaf+                        | Node (BTree a) a (BTree a)++    export+    insert : Ord a => a -> BTree a -> BTree a+    insert x Leaf = Node Leaf x Leaf+    insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)+                                       else (Node l v (insert x r))++    export+    toList : BTree a -> List a+    toList Leaf = []+    toList (Node l v r) = Btree.toList l ++ (v :: Btree.toList r)++    export+    toTree : Ord a => List a -> BTree a+    toTree [] = Leaf+    toTree (x :: xs) = insert x (toTree xs)++``%access`` Directive+----------------------++Finally, the default export mode can be changed with the ``%access``+directive, for example:++.. code-block:: idris++    module Btree++    %access export++    data BTree a = Leaf+                          | Node (BTree a) a (BTree a)++    insert : Ord a => a -> BTree a -> BTree a+    insert x Leaf = Node Leaf x Leaf+    insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)+                                       else (Node l v (insert x r))++    toList : BTree a -> List a+    toList Leaf = []+    toList (Node l v r) = Btree.toList l ++ (v :: Btree.toList r)++    toTree : Ord a => List a -> BTree a+    toTree [] = Leaf+    toTree (x :: xs) = insert x (toTree xs)++In this case, any function with no access modifier will be exported as+``export``, rather than left ``private``.++Propagating Inner Module API's+-------------------------------++Additionally, a module can re-export a module it has imported, by using+the ``public`` modifier on an ``import``. For example:++.. code-block:: idris++    module A++    import B+    import public C++    public a : AType a = ...++The module ``A`` will export the name ``a``, as well as any public or+abstract names in module ``C``, but will not re-export anything from+module ``B``.++Explicit Namespaces+===================++Defining a module also defines a namespace implicitly. However,+namespaces can also be given *explicitly*. This is most useful if you+wish to overload names within the same module:++.. code-block:: idris++    module Foo++    namespace x+      test : Int -> Int+      test x = x * 2++    namespace y+      test : String -> String+      test x = x ++ x++This (admittedly contrived) module defines two functions with fully+qualified names ``foo.x.test`` and ``foo.y.test``, which can be+disambiguated by their types:++::++    *foo> test 3+    6 : Int+    *foo> test "foo"+    "foofoo" : String++Parameterised blocks+====================++Groups of functions can be parameterised over a number of arguments+using a ``parameters`` declaration, for example:++.. code-block:: idris++    parameters (x : Nat, y : Nat)+      addAll : Nat -> Nat+      addAll z = x + y + z++The effect of a ``parameters`` block is to add the declared parameters+to every function, type and data constructor within the+block. Specifically, adding the parameters to the front of the+argument list. Outside the block, the parameters must be given+explicitly. The ``addAll`` function, when called from the REPL, will+thus have the following type signature.++::++    *params> :t addAll+    addAll : Nat -> Nat -> Nat -> Nat++and the following definition.++.. code-block:: idris++    addAll : (x : Nat) -> (y : Nat) -> (z : Nat) -> Nat+    addAll x y z = x + y + z++Parameters blocks can be nested, and can also include data declarations,+in which case the parameters are added explicitly to all type and data+constructors. They may also be dependent types with implicit arguments:++.. code-block:: idris++    parameters (y : Nat, xs : Vect x a)+      data Vects : Type -> Type where+        MkVects : Vect y a -> Vects a++      append : Vects a -> Vect (x + y) a+      append (MkVects ys) = xs ++ ys++To use ``Vects`` or ``append`` outside the block, we must also give the+``xs`` and ``y`` arguments. Here, we can use placeholders for the values+which can be inferred by the type checker:++::++    *params> show (append _ _ (MkVects _ [1,2,3] [4,5,6]))+    "[1, 2, 3, 4, 5, 6]" : String
+ docs/tutorial/packages.rst view
@@ -0,0 +1,67 @@+********+Packages+********+++Idris includes a simple build system for building packages and executables from a named package description file.+These files can be used with the Idris compiler to manage the development process .++Package Descriptions+====================++A package description includes the following:+++ A header, consisting of the keyword package followed by the package+  name. Package names can be any valid Idris identifier. The iPKG+  format also takes a quoted version that accepts any valid filename.++ Fields describing package contents, ``<field> = <value>``++At least one field must be the modules field, where the value is a+comma separated list of modules.  For example, given an idris package+``maths`` that has modules ``Maths.idr``, ``Maths.NumOps.idr``,+``Maths.BinOps.idr``, and ``Maths.HexOps.idr``, the corresponding+package file would be::++    package maths++    modules = Maths+            , Maths.NumOps+            , Maths.BinOps+            , Maths.HexOps+++Other examples of package files can be found in the ``libs`` directory+of the main Idris repository, and in `third-party libraries <https://github.com/idris-lang/Idris-dev/wiki/Libraries>`_.+More details including a complete listing of available fields can be found in :ref:`ref-sect-packages`.+++Using Package files+===================++Given an Idris package file ``maths.ipkg`` it can be used with the Idris compiler as follows:+++ ``idris --build maths.ipkg`` will build all modules in the package+++ ``idris --install maths.ipkg`` will install the package, making it+  accessible by other Idris libraries and programs.+++ ``idris --clean maths.ipkg`` will delete all intermediate code and+  executable files generated when building.+++ ``idris --mkdoc maths.ipkg`` will build HTML documentation for your+  package in the folder ``maths_doc`` in your project's root+  directory.+++ ``idris --checkpkg maths.ipkg`` will type check all modules in the+  package only. This differs from build that type checks **and**+  generates code.+++ ``idris --testpkg maths.ipkg`` will compile and run any embedded+  tests you have specified in the ``tests`` parameter. More+  information about testing is given in the next section.++Once the maths package has been installed, the command line option+``--package maths`` makes it accessible (abbreviated to ``-p maths``).+For example::++    idris -p maths Main.idr
+ docs/tutorial/provisional.rst view
@@ -0,0 +1,277 @@+.. _sect-provisional:++***********************+Provisional Definitions+***********************++Sometimes when programming with dependent types, the type required by+the type checker and the type of the program we have written will be+different (in that they do not have the same normal form), but+nevertheless provably equal. For example, recall the ``parity``+function:++.. code-block:: idris++    data Parity : Nat -> Type where+       Even : Parity (n + n)+       Odd  : Parity (S (n + n))++We’d like to implement this as follows:++.. code-block:: idris++    parity : (n:Nat) -> Parity n+    parity Z     = Even {n=Z}+    parity (S Z) = Odd {n=Z}+    parity (S (S k)) with (parity k)+      parity (S (S (j + j)))     | Even = Even {n=S j}+      parity (S (S (S (j + j)))) | Odd  = Odd {n=S j}++This simply states that zero is even, one is odd, and recursively, the+parity of ``k+2`` is the same as the parity of ``k``. Explicitly marking+the value of ``n`` is even and odd is necessary to help type inference.+Unfortunately, the type checker rejects this:++::++    viewsbroken.idr:12:10:When elaborating right hand side of ViewsBroken.parity:+    Type mismatch between +        Parity (plus (S j) (S j))+    and+        Parity (S (S (plus j j)))++    Specifically:+        Type mismatch between+            plus (S j) (S j)+        and+            S (S (plus j j))++The type checker is telling us that ``(j+1)+(j+1)`` and ``2+j+j`` do not+normalise to the same value. This is because ``plus`` is defined by+recursion on its first argument, and in the second value, there is a+successor symbol on the second argument, so this will not help with+reduction. These values are obviously equal — how can we rewrite the+program to fix this problem?++Provisional definitions+=======================++*Provisional definitions* help with this problem by allowing us to defer+the proof details until a later point. There are two main reasons why+they are useful.++-  When *prototyping*, it is useful to be able to test programs before+   finishing all the details of proofs.++-  When *reading* a program, it is often much clearer to defer the proof+   details so that they do not distract the reader from the underlying+   algorithm.++Provisional definitions are written in the same way as ordinary+definitions, except that they introduce the right hand side with a+``?=`` rather than ``=``. We define ``parity`` as follows:++.. code-block:: idris++    parity : (n:Nat) -> Parity n+    parity Z = Even {n=Z}+    parity (S Z) = Odd {n=Z}+    parity (S (S k)) with (parity k)+      parity (S (S (j + j))) | Even ?= Even {n=S j}+      parity (S (S (S (j + j)))) | Odd ?= Odd {n=S j}++When written in this form, instead of reporting a type error, Idris+will insert a hole standing for a theorem which will correct the+type error. Idris tells us we have two proof obligations, with names+generated from the module and function names:++.. code-block:: idris++    *views> :m+    Global holes:+            [views.parity_lemma_2,views.parity_lemma_1]++The first of these has the following type:++.. code-block:: idris++    *views> :p views.parity_lemma_1++    ---------------------------------- (views.parity_lemma_1) --------+    {hole0} : (j : Nat) -> (Parity (plus (S j) (S j))) -> Parity (S (S (plus j j)))++    -views.parity_lemma_1>++The two arguments are ``j``, the variable in scope from the pattern+match, and ``value``, which is the value we gave in the right hand side+of the provisional definition. Our goal is to rewrite the type so that+we can use this value. We can achieve this using the following theorem+from the prelude:++.. code-block:: idris++    plusSuccRightSucc : (left : Nat) -> (right : Nat) ->+      S (left + right) = left + (S right)++We need to use ``compute`` again to unfold the definition of ``plus``:++.. code-block:: idris++    -views.parity_lemma_1> compute+++    ---------------------------------- (views.parity_lemma_1) --------+    {hole0} : (j : Nat) -> (Parity (S (plus j (S j)))) -> Parity (S (S (plus j j)))++After applying ``intros`` we have:++.. code-block:: idris++    -views.parity_lemma_1> intros++      j : Nat+      value : Parity (S (plus j (S j)))+    ---------------------------------- (views.parity_lemma_1) --------+    {hole2} : Parity (S (S (plus j j)))++Then we apply the ``plusSuccRightSucc`` rewrite rule, symmetrically, to+``j`` and ``j``, giving:++.. code-block:: idris++    -views.parity_lemma_1> rewrite sym (plusSuccRightSucc j j)++      j : Nat+      value : Parity (S (plus j (S j)))+    ---------------------------------- (views.parity_lemma_1) --------+    {hole3} : Parity (S (plus j (S j)))++``sym`` is a function, defined in the library, which reverses the order+of the rewrite:++.. code-block:: idris++    sym : l = r -> r = l+    sym Refl = Refl++We can complete this proof using the ``trivial`` tactic, which finds+``value`` in the premises. The proof of the second lemma proceeds in+exactly the same way.++We can now test the ``natToBin`` function from Section :ref:`sect-nattobin`+at the prompt. The number 42 is 101010 in binary. The binary digits are+reversed:++.. code-block:: idris++    *views> show (natToBin 42)+    "[False, True, False, True, False, True]" : String++Suspension of Disbelief+=======================++Idris requires that proofs be complete before compiling programs+(although evaluation at the prompt is possible without proof details).+Sometimes, especially when prototyping, it is easier not to have to do+this. It might even be beneficial to test programs before attempting to+prove things about them — if testing finds an error, you know you had+better not waste your time proving something!++Therefore, Idris provides a built-in coercion function, which allows+you to use a value of the incorrect types:++.. code-block:: idris++    believe_me : a -> b++Obviously, this should be used with extreme caution. It is useful when+prototyping, and can also be appropriate when asserting properties of+external code (perhaps in an external C library). The “proof” of+``views.parity_lemma_1`` using this is:++.. code-block:: idris++    views.parity_lemma_2 = proof {+        intro;+        intro;+        exact believe_me value;+    }++The ``exact`` tactic allows us to provide an exact value for the proof.+In this case, we assert that the value we gave was correct.++Example: Binary numbers+=======================++Previously, we implemented conversion to binary numbers using the+``Parity`` view. Here, we show how to use the same view to implement a+verified conversion to binary. We begin by indexing binary numbers over+their ``Nat`` equivalent. This is a common pattern, linking a+representation (in this case ``Binary``) with a meaning (in this case+``Nat``):++.. code-block:: idris++    data Binary : Nat -> Type where+       BEnd : Binary Z+       BO : Binary n -> Binary (n + n)+       BI : Binary n -> Binary (S (n + n))++``BO`` and ``BI`` take a binary number as an argument and effectively+shift it one bit left, adding either a zero or one as the new least+significant bit. The index, ``n + n`` or ``S (n + n)`` states the result+that this left shift then add will have to the meaning of the number.+This will result in a representation with the least significant bit at+the front.++Now a function which converts a Nat to binary will state, in the type,+that the resulting binary number is a faithful representation of the+original Nat:++.. code-block:: idris++    natToBin : (n:Nat) -> Binary n++The ``Parity`` view makes the definition fairly simple — halving the+number is effectively a right shift after all — although we need to use+a provisional definition in the Odd case:++.. code-block:: idris++    natToBin : (n:Nat) -> Binary n+    natToBin Z = BEnd+    natToBin (S k) with (parity k)+       natToBin (S (j + j))     | Even  = BI (natToBin j)+       natToBin (S (S (j + j))) | Odd  ?= BO (natToBin (S j))++The problem with the Odd case is the same as in the definition of+``parity``, and the proof proceeds in the same way:++.. code-block:: idris++    natToBin_lemma_1 = proof {+        intro;+        intro;+        rewrite sym (plusSuccRightSucc j j);+        trivial;+    }++To finish, we’ll implement a main program which reads an integer from+the user and outputs it in binary.++.. code-block:: idris++    main : IO ()+    main = do putStr "Enter a number: "+              x <- getLine+              print (natToBin (fromInteger (cast x)))++For this to work, of course, we need a ``Show`` implementation for+``Binary n``:++.. code-block:: idris++    Show (Binary n) where+        show (BO x) = show x ++ "0"+        show (BI x) = show x ++ "1"+        show BEnd = ""
+ docs/tutorial/starting.rst view
@@ -0,0 +1,92 @@+.. _sect-starting:++***************+Getting Started+***************++Prerequisites+=============++Before installing Idris, you will need to make sure you have all+of the necessary libraries and tools. You will need:++- A fairly recent Haskell platform. Version ``2013.2.0.0`` should be sufficiently recent, though it is better to be completely up to date.++- The *GNU Multiple Precision Arithmetic Library* (GMP) is available  from MacPorts/Homebrew and all major Linux distributions.++Downloading and Installing+==========================++The easiest way to install Idris, if you have all of the+prerequisites, is to type:++::++    cabal update; cabal install idris++This will install the latest version released on Hackage, along with+any dependencies. If, however, you would like the most up to date+development version you can find it, as well as build instructions, on+GitHub at: https://github.com/idris-lang/Idris-dev.++If you haven't previously installed anything using Cabal, then Idris+may not be on your path. Should the Idris executable not be found+please ensure that you have added ``~/.cabal/bin`` to your ``$PATH``+environment variable. Mac OS X users may find they need to add+``~/Library/Haskell/bin`` instead, and Windows users will typically+find that Cabal installs programs in ``%HOME%\AppData\Roaming\cabal\bin``.++To check that installation has succeeded, and to write your first+Idris program, create a file called ``hello.idr`` containing the+following text:++.. code-block:: idris++    module Main++    main : IO ()+    main = putStrLn "Hello world"++If you are familiar with Haskell, it should be fairly clear what the+program is doing and how it works, but if not, we will explain the+details later. You can compile the program to an executable by+entering ``idris hello.idr -o hello`` at the shell prompt. This will+create an executable called ``hello``, which you can run:++::++    $ idris hello.idr -o hello+    $ ./hello+    Hello world++Please note that the dollar sign ``$`` indicates the shell prompt!+Some useful options to the Idris command are:++- ``-o prog`` to compile to an executable called ``prog``.++- ``--check`` type check the file and its dependencies without starting the interactive environment.++- ``--package pkg`` add package as dependency, e.g. ``--package contrib`` to make use of the contrib package.++- ``--help`` display usage summary and command line options.++The Interactive Environment+===========================++Entering ``idris`` at the shell prompt starts up the interactive+environment. You should see something like the following:++.. literalinclude:: ../listing/idris-prompt-start.txt++This gives a ``ghci`` style interface which allows evaluation of, as+well as type checking of, expressions; theorem proving, compilation;+editing; and various other operations. The command ``:?`` gives a list+of supported commands. Below, we see an example run in+which ``hello.idr`` is loaded, the type of ``main`` is checked and+then the program is compiled to the executable ``hello``. Type+checking a file, if successful, creates a bytecode version of the file+(in this case ``hello.ibc``) to speed up loading in future. The+bytecode is regenerated if the source file changes.++.. _run1:+.. literalinclude:: ../listing/idris-prompt-helloworld.txt
+ docs/tutorial/syntax.rst view
@@ -0,0 +1,211 @@+.. _sect-syntax:++*****************+Syntax Extensions+*****************++Idris supports the implementation of *Embedded Domain Specific+Languages* (EDSLs) in several ways [1]_. One way, as we have already+seen, is through extending ``do`` notation. Another important way is+to allow extension of the core syntax. In this section we describe two+ways of extending the syntax: ``syntax`` rules and ``dsl`` notation.++``syntax`` rules+================++We have seen ``if...then...else`` expressions, but these are not built+in. Instead, we can define a function in the prelude as follows (we+have already seen this function in Section :ref:`sect-lazy`):++.. code-block:: idris++    ifThenElse : (x:Bool) -> Lazy a -> Lazy a -> a;+    ifThenElse True  t e = t;+    ifThenElse False t e = e;++and then extend the core syntax with a ``syntax`` declaration:++.. code-block:: idris++    syntax if [test] then [t] else [e] = ifThenElse test t e;++The left hand side of a ``syntax`` declaration describes the syntax+rule, and the right hand side describes its expansion. The syntax rule+itself consists of:++-  **Keywords** — here, ``if``, ``then`` and ``else``, which must be+   valid identifiers++-  **Non-terminals** — included in square brackets, ``[test]``, ``[t]``+   and ``[e]`` here, which stand for arbitrary expressions. To avoid+   parsing ambiguities, these expressions cannot use syntax extensions+   at the top level (though they can be used in parentheses).++-  **Names** — included in braces, which stand for names which may be+   bound on the right hand side.++-  **Symbols** — included in quotations marks, e.g. ``:=``. This can+   also be used to include reserved words in syntax rules, such as+   ``let`` or ``in``.++The limitations on the form of a syntax rule are that it must include+at least one symbol or keyword, and there must be no repeated+variables standing for non-terminals. Any expression can be used, but+if there are two non-terminals in a row in a rule, only simple+expressions may be used (that is, variables, constants, or bracketed+expressions). Rules can use previously defined rules, but may not be+recursive. The following syntax extensions would therefore be valid:++.. code-block:: idris++    syntax [var] ":=" [val]                = Assign var val;+    syntax [test] "?" [t] ":" [e]          = if test then t else e;+    syntax select [x] from [t] "where" [w] = SelectWhere x t w;+    syntax select [x] from [t]             = Select x t;++Syntax macros can be further restricted to apply only in patterns (i.e.,+only on the left hand side of a pattern match clause) or only in terms+(i.e. everywhere but the left hand side of a pattern match clause) by+being marked as ``pattern`` or ``term`` syntax rules. For example, we+might define an interval as follows, with a static check that the lower+bound is below the upper bound using ``so``:++.. code-block:: idris++    data Interval : Type where+       MkInterval : (lower : Double) -> (upper : Double) ->+                    so (lower < upper) -> Interval++We can define a syntax which, in patterns, always matches ``oh`` for+the proof argument, and in terms requires a proof term to be provided:++.. code-block:: idris++    pattern syntax "[" [x] "..." [y] "]" = MkInterval x y oh+    term    syntax "[" [x] "..." [y] "]" = MkInterval x y ?bounds_lemma++In terms, the syntax ``[x...y]`` will generate a proof obligation+``bounds_lemma`` (possibly renamed).++Finally, syntax rules may be used to introduce alternative binding+forms. For example, a ``for`` loop binds a variable on each iteration:++.. code-block:: idris++    syntax for {x} in [xs] ":" [body] = forLoop xs (\x => body)++    main : IO ()+    main = do for x in [1..10]:+                  putStrLn ("Number " ++ show x)+              putStrLn "Done!"++Note that we have used the ``{x}`` form to state that ``x`` represents+a bound variable, substituted on the right hand side. We have also put+``in`` in quotation marks since it is already a reserved word.++``dsl`` notation+================++The well-typed interpreter in Section :ref:`sect-interp` is a simple+example of a common programming pattern with dependent types. Namely:+describe an *object language* and its type system with dependent types+to guarantee that only well-typed programs can be represented, then+program using that representation. Using this approach we can, for+example, write programs for serialising binary data [2]_ or running+concurrent processes safely [3]_.++Unfortunately, the form of object language programs makes it rather+hard to program this way in practice. Recall the factorial program in+``Expr`` for example:++.. code-block:: idris++    fact : Expr G (TyFun TyInt TyInt)+    fact = Lam (If (Op (==) (Var Stop) (Val 0))+                   (Val 1) (Op (*) (App fact (Op (-) (Var Stop) (Val 1)))+                                   (Var Stop)))++Since this is a particularly useful pattern, Idris provides syntax+overloading [1]_ to make it easier to program in such object+languages:++.. code-block:: idris++    mkLam : TTName -> Expr (t::g) t' -> Expr g (TyFun t t')+    mkLam _ body = Lam body++    dsl expr+        variable    = Var+        index_first = Stop+        index_next  = Pop+        lambda      = mkLam++A ``dsl`` block describes how each syntactic construct is represented+in an object language. Here, in the ``expr`` language, any variable is+translated to the ``Var`` constructor, using ``Pop`` and ``Stop`` to+construct the de Bruijn index (i.e., to count how many bindings since+the variable itself was bound); and any lambda is translated to a+``Lam`` constructor. The ``mkLam`` function simply ignores its first+argument, which is the name that the user chose for the variable. It+is also possible to overload ``let`` and dependent function syntax+(``pi``) in this way. We can now write ``fact`` as follows:++.. code-block:: idris++    fact : Expr G (TyFun TyInt TyInt)+    fact = expr (\x => If (Op (==) x (Val 0))+                          (Val 1) (Op (*) (app fact (Op (-) x (Val 1))) x))++In this new version, ``expr`` declares that the next expression will+be overloaded. We can take this further, using idiom brackets, by+declaring:++.. code-block:: idris++    (<*>) : (f : Lazy (Expr G (TyFun a t))) -> Expr G a -> Expr G t+    (<*>) f a = App f a++    pure : Expr G a -> Expr G a+    pure = id++Note that there is no need for these to be part of an implementation of+``Applicative``, since idiom bracket notation translates directly to+the names ``<*>`` and ``pure``, and ad-hoc type-directed overloading+is allowed. We can now say:++.. code-block:: idris++    fact : Expr G (TyFun TyInt TyInt)+    fact = expr (\x => If (Op (==) x (Val 0))+                          (Val 1) (Op (*) [| fact (Op (-) x (Val 1)) |] x))++With some more ad-hoc overloading and use of interfaces, and a new+syntax rule, we can even go as far as:++.. code-block:: idris++    syntax "IF" [x] "THEN" [t] "ELSE" [e] = If x t e++    fact : Expr G (TyFun TyInt TyInt)+    fact = expr (\x => IF x == 0 THEN 1 ELSE [| fact (x - 1) |] * x)+++.. [1] Edwin Brady and Kevin Hammond. 2012. Resource-Safe systems+       programming with embedded domain specific languages. In+       Proceedings of the 14th international conference on Practical+       Aspects of Declarative Languages (PADL'12), Claudio Russo and+       Neng-Fa Zhou (Eds.). Springer-Verlag, Berlin, Heidelberg,+       242-257. DOI=10.1007/978-3-642-27694-1_18+       http://dx.doi.org/10.1007/978-3-642-27694-1_18++.. [2] Edwin C. Brady. 2011. IDRIS ---: systems programming meets full+       dependent types. In Proceedings of the 5th ACM workshop on+       Programming languages meets program verification (PLPV+       '11). ACM, New York, NY, USA,+       43-54. DOI=10.1145/1929529.1929536+       http://doi.acm.org/10.1145/1929529.1929536++.. [3] Edwin Brady and Kevin Hammond. 2010. Correct-by-Construction+       Concurrency: Using Dependent Types to Verify Implementations of+       Effectful Resource Usage Protocols. Fundam. Inf. 102, 2 (April+       2010), 145-176. http://dl.acm.org/citation.cfm?id=1883636
+ docs/tutorial/testing.rst view
@@ -0,0 +1,85 @@+.. _tut-sect-testing:++**********************+Testing Idris Packages+**********************++The integrated build system includes a simple testing framework.+This framework collects functions listed in the ``ipkg`` file under ``tests``.+All test functions must return ``IO ()``.+++When you enter ``idris --testpkg yourmodule.ipkg``,+the build system creates a temporary file in a fresh environment on your machine+by listing the ``tests`` functions under a single ``main`` function.+It compiles this temporary file to an executable and then executes it.+++The tests themselves are responsible for reporting their success or failure.+Test functions commonly use ``putStrLn`` to report test results.+The test framework does not impose any standards for reporting and consequently+does not aggregate test results.+++For example, lets take the following list of functions that are defined in a module called ``NumOps`` for a sample package ``maths``.++.. name: Math/NumOps.idr+.. code-block:: idris++    module Maths.NumOps++    double : Num a => a -> a+    double a = a + a++    triple : Num a => a -> a+    triple a = a + double a++A simple test module, with a qualified name of ``Test.NumOps`` can be declared as++.. name: Math/TestOps.idr+.. code-block:: idris++    module Test.NumOps++    import Maths.NumOps++    assertEq : Eq a => (given : a) -> (expected : a) -> IO ()+    assertEq g e = if g == e+        then putStrLn "Test Passed"+        else putStrLn "Test Failed"++    assertNotEq : Eq a => (given : a) -> (expected : a) -> IO ()+    assertNotEq g e = if not (g == e)+        then putStrLn "Test Passed"+        else putStrLn "Test Failed"++    testDouble : IO ()+    testDouble = assertEq (double 2) 4++    testTriple : IO ()+    testTriple = assertNotEq (triple 2) 5+++The functions ``assertEq`` and ``assertNotEq`` are used to run expected passing, and failing, equality tests.+The actual tests are ``testDouble`` and ``testTriple``, and are declared in the ``maths.ipkg`` file as follows::++    package maths++    modules = Maths.NumOps+            , Test.NumOps++    tests = Test.NumOps.testDouble+          , Test.NumOps.testTriple+++The testing framework can then be invoked using ``idris --testpkg maths.ipkg``::++    > idris --testpkg maths.ipkg+    Type checking ./Maths/NumOps.idr+    Type checking ./Test/NumOps.idr+    Type checking /var/folders/63/np5g0d5j54x1s0z12rf41wxm0000gp/T/idristests144128232716531729.idr+    Test Passed+    Test Passed++Note how both tests have reported success by printing ``Test Passed``+as we arranged for with the ``assertEq`` and ``assertNoEq`` functions.
+ docs/tutorial/theorems.rst view
@@ -0,0 +1,291 @@+.. _sect-theorems:++***************+Theorem Proving+***************++Equality+========++Idris allows propositional equalities to be declared, allowing theorems about+programs to be stated and proved. Equality is built in, but conceptually+has the following definition:++.. code-block:: idris++    data (=) : a -> b -> Type where+       Refl : x = x++Equalities can be proposed between any values of any types, but the only+way to construct a proof of equality is if values actually are equal.+For example:++.. code-block:: idris++    fiveIsFive : 5 = 5+    fiveIsFive = Refl++    twoPlusTwo : 2 + 2 = 4+    twoPlusTwo = Refl++.. _sect-empty:++The Empty Type+==============++There is an empty type, :math:`\bot`, which has no constructors. It is+therefore impossible to construct an element of the empty type, at least+without using a partially defined or general recursive function (see+Section :ref:`sect-totality` for more details). We can therefore use the+empty type to prove that something is impossible, for example zero is+never equal to a successor:++.. code-block:: idris++    disjoint : (n : Nat) -> Z = S n -> Void+    disjoint n p = replace {P = disjointTy} p ()+      where+        disjointTy : Nat -> Type+        disjointTy Z = ()+        disjointTy (S k) = Void++There is no need to worry too much about how this function works —+essentially, it applies the library function ``replace``, which uses an+equality proof to transform a predicate. Here we use it to transform a+value of a type which can exist, the empty tuple, to a value of a type+which can’t, by using a proof of something which can’t exist.++Once we have an element of the empty type, we can prove anything.+``void`` is defined in the library, to assist with proofs by+contradiction.++.. code-block:: idris++    void : Void -> a++Simple Theorems+===============++When type checking dependent types, the type itself gets *normalised*.+So imagine we want to prove the following theorem about the reduction+behaviour of ``plus``:++.. code-block:: idris++    plusReduces : (n:Nat) -> plus Z n = n++We’ve written down the statement of the theorem as a type, in just the+same way as we would write the type of a program. In fact there is no+real distinction between proofs and programs. A proof, as far as we are+concerned here, is merely a program with a precise enough type to+guarantee a particular property of interest.++We won’t go into details here, but the Curry-Howard correspondence [1]_+explains this relationship. The proof itself is trivial, because+``plus Z n`` normalises to ``n`` by the definition of ``plus``:++.. code-block:: idris++    plusReduces n = Refl++It is slightly harder if we try the arguments the other way, because+plus is defined by recursion on its first argument. The proof also works+by recursion on the first argument to ``plus``, namely ``n``.++.. code-block:: idris++    plusReducesZ : (n:Nat) -> n = plus n Z+    plusReducesZ Z = Refl+    plusReducesZ (S k) = cong (plusReducesZ k)++``cong`` is a function defined in the library which states that equality+respects function application:++.. code-block:: idris++    cong : {f : t -> u} -> a = b -> f a = f b++We can do the same for the reduction behaviour of plus on successors:++.. code-block:: idris++    plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m)+    plusReducesS Z m = Refl+    plusReducesS (S k) m = cong (plusReducesS k m)++Even for trivial theorems like these, the proofs are a little tricky to+construct in one go. When things get even slightly more complicated, it+becomes too much to think about to construct proofs in this ‘batch+mode’.++Idris provides interactive editing capabilities, which can help with+building proofs. For more details on building proofs interactively in+an editor, see :ref:`proofs-index`.++.. _sect-totality:++Totality Checking+=================++If we really want to trust our proofs, it is important that they are+defined by *total* functions — that is, a function which is defined for+all possible inputs and is guaranteed to terminate. Otherwise we could+construct an element of the empty type, from which we could prove+anything:++.. code-block:: idris++    -- making use of 'hd' being partially defined+    empty1 : Void+    empty1 = hd [] where+        hd : List a -> a+        hd (x :: xs) = x++    -- not terminating+    empty2 : Void+    empty2 = empty2++Internally, Idris checks every definition for totality, and we can check at+the prompt with the ``:total`` command. We see that neither of the above+definitions is total:++::++    *theorems> :total empty1+    possibly not total due to: empty1#hd+        not total as there are missing cases+    *theorems> :total empty2+    possibly not total due to recursive path empty2++Note the use of the word “possibly” — a totality check can, of course,+never be certain due to the undecidability of the halting problem. The+check is, therefore, conservative. It is also possible (and indeed+advisable, in the case of proofs) to mark functions as total so that it+will be a compile time error for the totality check to fail:++.. code-block:: idris++    total empty2 : Void+    empty2 = empty2++::++    Type checking ./theorems.idr+    theorems.idr:25:empty2 is possibly not total due to recursive path empty2++Reassuringly, our proof in Section :ref:`sect-empty` that the zero and+successor constructors are disjoint is total:++.. code-block:: idris++    *theorems> :total disjoint+    Total++The totality check is, necessarily, conservative. To be recorded as+total, a function ``f`` must:++-  Cover all possible inputs++-  Be *well-founded* — i.e. by the time a sequence of (possibly+   mutually) recursive calls reaches ``f`` again, it must be possible to+   show that one of its arguments has decreased.++-  Not use any data types which are not *strictly positive*++-  Not call any non-total functions++Directives and Compiler Flags for Totality+------------------------------------------++By default, Idris allows all well-typed definitions, whether total or not.+However, it is desirable for functions to be total as far as possible, as this+provides a guarantee that they provide a result for all possible inputs, in+finite time. It is possible to make total functions a requirement, either:++-  By using the ``--total`` compiler flag.++-  By adding a ``%default total`` directive to a source file. All+   definitions after this will be required to be total, unless+   explicitly flagged as ``partial``.++All functions *after* a ``%default total`` declaration are required to+be total. Correspondingly, after a ``%default partial`` declaration, the+requirement is relaxed.++Finally, the compiler flag ``--warnpartial`` causes to print a warning+for any undeclared partial function.++Totality checking issues+------------------------++Please note that the totality checker is not perfect! Firstly, it is+necessarily conservative due to the undecidability of the halting+problem, so many programs which *are* total will not be detected as+such. Secondly, the current implementation has had limited effort put+into it so far, so there may still be cases where it believes a function+is total which is not. Do not rely on it for your proofs yet!++Hints for totality+------------------++In cases where you believe a program is total, but Idris does not agree, it is+possible to give hints to the checker to give more detail for a termination+argument. The checker works by ensuring that all chains of recursive calls+eventually lead to one of the arguments decreasing towards a base case, but+sometimes this is hard to spot. For example, the following definition cannot be+checked as ``total`` because the checker cannot decide that ``filter (<= x) xs``+will always be smaller than ``(x :: xs)``:++.. code-block:: idris++    qsort : Ord a => List a -> List a+    qsort [] = []+    qsort (x :: xs)+       = qsort (filter (< x) xs) +++          (x :: qsort (filter (>= x) xs))++The function ``assert_smaller``, defined in the Prelude, is intended to+address this problem:++.. code-block:: idris++    assert_smaller : a -> a -> a+    assert_smaller x y = y++It simply evaluates to its second argument, but also asserts to the+totality checker that ``y`` is structurally smaller than ``x``. This can+be used to explain the reasoning for totality if the checker cannot work+it out itself. The above example can now be written as:++.. code-block:: idris++    total+    qsort : Ord a => List a -> List a+    qsort [] = []+    qsort (x :: xs)+       = qsort (assert_smaller (x :: xs) (filter (< x) xs)) +++          (x :: qsort (assert_smaller (x :: xs) (filter (>= x) xs)))++The expression ``assert_smaller (x :: xs) (filter (<= x) xs)`` asserts+that the result of the filter will always be smaller than the pattern+``(x :: xs)``.++In more extreme cases, the function ``assert_total`` marks a+subexpression as always being total:++.. code-block:: idris++    assert_total : a -> a+    assert_total x = x++In general, this function should be avoided, but it can be very useful+when reasoning about primitives or externally defined functions (for+example from a C library) where totality can be shown by an external+argument.+++.. [1] Timothy G. Griffin. 1989. A formulae-as-type notion of+       control. In Proceedings of the 17th ACM SIGPLAN-SIGACT+       symposium on Principles of programming languages (POPL+       '90). ACM, New York, NY, USA, 47-58. DOI=10.1145/96709.96714+       http://doi.acm.org/10.1145/96709.96714
+ docs/tutorial/typesfuns.rst view
@@ -0,0 +1,1352 @@+.. _sect-typefuns:++*******************+Types and Functions+*******************++Primitive Types+===============++Idris defines several primitive types: ``Int``, ``Integer`` and+``Double`` for numeric operations, ``Char`` and ``String`` for text+manipulation, and ``Ptr`` which represents foreign pointers. There are+also several data types declared in the library, including ``Bool``,+with values ``True`` and ``False``. We can declare some constants with+these types. Enter the following into a file ``Prims.idr`` and load it+into the Idris interactive environment by typing ``idris+Prims.idr``:++.. code-block:: idris++    module Prims++    x : Int+    x = 42++    foo : String+    foo = "Sausage machine"++    bar : Char+    bar = 'Z'++    quux : Bool+    quux = False++An Idris file consists of an optional module declaration (here+``module Prims``) followed by an optional list of imports and a+collection of declarations and definitions. In this example no imports+have been specified. However Idris programs can consist of several+modules and the definitions in each module each have their own+namespace. This is discussed further in Section+:ref:`sect-namespaces`). When writing Idris programs both the order in which+definitions are given and indentation are significant. Functions and+data types must be defined before use, incidentally each definition must+have a type declaration, for example see ``x : Int``, ``foo :+String``, from the above listing. New declarations must begin at the+same level of indentation as the preceding declaration.+Alternatively, a semicolon ``;`` can be used to terminate declarations.++A library module ``prelude`` is automatically imported by every+Idris program, including facilities for IO, arithmetic, data+structures and various common functions. The prelude defines several+arithmetic and comparison operators, which we can use at the prompt.+Evaluating things at the prompt gives an answer, and the type of the+answer. For example:++::++    *prims> 6*6+6+    42 : Integer+    *prims> x == 6*6+6+    True : Bool++All of the usual arithmetic and comparison operators are defined for+the primitive types. They are overloaded using interfaces, as we+will discuss in Section :ref:`sect-interfaces` and can be extended to+work on user defined types. Boolean expressions can be tested with the+``if...then...else`` construct, for example:++::++    *prims> if x == 6 * 6 + 6 then "The answer!" else "Not the answer"+    "The answer!" : String++Data Types+==========++Data types are declared in a similar way and with similar syntax to+Haskell. Natural numbers and lists, for example, can be declared as+follows:++.. code-block:: idris++    data Nat    = Z   | S Nat           -- Natural numbers+                                        -- (zero and successor)+    data List a = Nil | (::) a (List a) -- Polymorphic lists++The above declarations are taken from the standard library. Unary+natural numbers can be either zero (``Z``), or the successor of+another natural number (``S k``). Lists can either be empty (``Nil``)+or a value added to the front of another list (``x :: xs``). In the+declaration for ``List``, we used an infix operator ``::``. New+operators such as this can be added using a fixity declaration, as+follows:++::++    infixr 10 ::++Functions, data constructors and type constructors may all be given+infix operators as names. They may be used in prefix form if enclosed+in brackets, e.g. ``(::)``. Infix operators can use any of the+symbols:++::++    :+-*\/=.?|&><!@$%^~#++Some operators built from these symbols can't be user defined. These are+``:``,  ``=>``,  ``->``,  ``<-``,  ``=``,  ``?=``,  ``|``,  ``**``,+``==>``,  ``\``,  ``%``,  ``~``,  ``?``,  and ``!``.++Functions+=========++Functions are implemented by pattern matching, again using a similar+syntax to Haskell. The main difference is that Idris requires type+declarations for all functions, using a single colon ``:`` (rather+than Haskell’s double colon ``::``). Some natural number arithmetic+functions can be defined as follows, again taken from the standard+library:++.. code-block:: idris++    -- Unary addition+    plus : Nat -> Nat -> Nat+    plus Z     y = y+    plus (S k) y = S (plus k y)++    -- Unary multiplication+    mult : Nat -> Nat -> Nat+    mult Z     y = Z+    mult (S k) y = plus y (mult k y)++The standard arithmetic operators ``+`` and ``*`` are also overloaded+for use by ``Nat``, and are implemented using the above functions.+Unlike Haskell, there is no restriction on whether types and function+names must begin with a capital letter or not. Function names+(``plus`` and ``mult`` above), data constructors (``Z``, ``S``,+``Nil`` and ``::``) and type constructors (``Nat`` and ``List``) are+all part of the same namespace. By convention, however,+data types and constructor names typically begin with a capital letter.+We can test these functions at the Idris prompt:++::++    Idris> plus (S (S Z)) (S (S Z))+    4 : Nat+    Idris> mult (S (S (S Z))) (plus (S (S Z)) (S (S Z)))+    12 : Nat++.. note::++   When displaying an element of ``Nat`` such as ``(S (S (S (S Z))))``,+   Idris displays it as ``4``.+   The result of ``plus (S (S Z)) (S (S Z))``+   is actually ``(S (S (S (S Z))))``+   which is the natural number ``4``.+   This can be checked at the Idris prompt:++::++    Idris> (S (S (S (S Z))))+    4 : Nat++Like arithmetic operations, integer literals are also overloaded using+interfaces, meaning that we can also test the functions as follows:++::++    Idris> plus 2 2+    4 : Nat+    Idris> mult 3 (plus 2 2)+    12 : Nat++You may wonder, by the way, why we have unary natural numbers when our+computers have perfectly good integer arithmetic built in. The reason+is primarily that unary numbers have a very convenient structure which+is easy to reason about, and easy to relate to other data structures+as we will see later. Nevertheless, we do not want this convenience to+be at the expense of efficiency. Fortunately, Idris knows about+the relationship between ``Nat`` (and similarly structured types) and+numbers. This means it can optimise the representation, and functions+such as ``plus`` and ``mult``.++``where`` clauses+-----------------++Functions can also be defined *locally* using ``where`` clauses. For+example, to define a function which reverses a list, we can use an+auxiliary function which accumulates the new, reversed list, and which+does not need to be visible globally:++.. code-block:: idris++    reverse : List a -> List a+    reverse xs = revAcc [] xs where+      revAcc : List a -> List a -> List a+      revAcc acc [] = acc+      revAcc acc (x :: xs) = revAcc (x :: acc) xs++Indentation is significant — functions in the ``where`` block must be+indented further than the outer function.++.. note:: Scope++    Any names which are visible in the outer scope are also visible in+    the ``where`` clause (unless they have been redefined, such as ``xs``+    here). A name which appears only in the type will be in scope in the+    ``where`` clause if it is a *parameter* to one of the types, i.e. it+    is fixed across the entire structure.++As well as functions, ``where`` blocks can include local data+declarations, such as the following where ``MyLT`` is not accessible+outside the definition of ``foo``:++.. code-block:: idris++    foo : Int -> Int+    foo x = case isLT of+                Yes => x*2+                No => x*4+        where+           data MyLT = Yes | No++           isLT : MyLT+           isLT = if x < 20 then Yes else No++In general, functions defined in a ``where`` clause need a type+declaration just like any top level function. However, the type+declaration for a function ``f`` *can* be omitted if:++- ``f`` appears in the right hand side of the top level definition++- The type of ``f`` can be completely determined from its first application+++So, for example, the following definitions are legal:++.. code-block:: idris++    even : Nat -> Bool+    even Z = True+    even (S k) = odd k where+      odd Z = False+      odd (S k) = even k++    test : List Nat+    test = [c (S 1), c Z, d (S Z)]+      where c x = 42 + x+            d y = c (y + 1 + z y)+                  where z w = y + w+++Dependent Types+===============++First Class Types+-----------------++In Idris, types are a first class language construct, meaning that they+can be computed and manipulated (and passed to functions) just like any+other language construct. For example, we could write a function which+computes a type:++.. code-block:: idris++    isSingleton : Bool -> Type+    isSingleton True = Nat+    isSingleton False = List Nat++This function calculates the appropriate type from a ``Bool`` which flags+whether the type should be a singleton or not. We can use this function+to calculate a type anywhere that a type can be used. For example, it+can be used to calculate a return type:++.. code-block:: idris++    mkSingle : (x : Bool) -> isSingleton x+    mkSingle True = 0+    mkSingle False = []++Or it can be used to have varying input types. The following function+calculates either the sum of a list of ``Nat``, or returns the given+``Nat``, depending on whether the singleton flag is true:++.. code-block:: idris++    sum : (single : Bool) -> isSingleton single -> Nat+    sum True x = x+    sum False [] = 0+    sum False (x :: xs) = x + sum False xs++Vectors+-------++A standard example of a dependent data type is the type of “lists with+length”, conventionally called vectors in the dependent type+literature.  They are available as part of the Idris library, by+importing ``Data.Vect``, or we can declare them as follows:++.. code-block:: idris++    data Vect : Nat -> Type -> Type where+       Nil  : Vect Z a+       (::) : a -> Vect k a -> Vect (S k) a++Note that we have used the same constructor names as for ``List``.+Ad-hoc name overloading such as this is accepted by Idris,+provided that the names are declared in different namespaces (in+practice, normally in different modules). Ambiguous constructor names+can normally be resolved from context.++This declares a family of types, and so the form of the declaration is+rather different from the simple type declarations above. We+explicitly state the type of the type constructor ``Vect`` — it takes+a ``Nat`` and a type as an argument, where ``Type`` stands for the+type of types. We say that ``Vect`` is *indexed* over ``Nat`` and+*parameterised* by ``Type``. Each constructor targets a different part+of the family of types. ``Nil`` can only be used to construct vectors+with zero length, and ``::`` to construct vectors with non-zero+length. In the type of ``::``, we state explicitly that an element of+type ``a`` and a tail of type ``Vect k a`` (i.e., a vector of length+``k``) combine to make a vector of length ``S k``.++We can define functions on dependent types such as ``Vect`` in the same+way as on simple types such as ``List`` and ``Nat`` above, by pattern+matching. The type of a function over ``Vect`` will describe what+happens to the lengths of the vectors involved. For example, ``++``,+defined as follows, appends two ``Vect``:++.. code-block:: idris++    (++) : Vect n a -> Vect m a -> Vect (n + m) a+    (++) Nil       ys = ys+    (++) (x :: xs) ys = x :: xs ++ ys++The type of ``(++)`` states that the resulting vector’s length will be+the sum of the input lengths. If we get the definition wrong in such a+way that this does not hold, Idris will not accept the definition.+For example:++.. code-block:: idris++    (++) : Vect n a -> Vect m a -> Vect (n + m) a+    (++) Nil       ys = ys+    (++) (x :: xs) ys = x :: xs ++ xs -- BROKEN++When run through the Idris type checker, this results in the+following:++::++    $ idris vbroken.idr --check+    vbroken.idr:9:23:When elaborating right hand side of Vect.++:+    When elaborating an application of constructor Vect.:::+        Type mismatch between+                Vect (k + k) a (Type of xs ++ xs)+        and+                Vect (plus k m) a (Expected type)++        Specifically:+                Type mismatch between+                        plus k k+                and+                        plus k m+++This error message suggests that there is a length mismatch between+two vectors — we needed a vector of length ``k + m``, but provided a+vector of length ``k + k``.++The Finite Sets+---------------++Finite sets, as the name suggests, are sets with a finite number of+elements. They are available as part of the Idris library, by+importing ``Data.Fin``, or can be declared as follows:++.. code-block:: idris++    data Fin : Nat -> Type where+       FZ : Fin (S k)+       FS : Fin k -> Fin (S k)++From the signature,  we can see that this is a type constructor that takes a ``Nat``, and produces a type.+So this is not a set in the sense of a collection that is a container of objects,+rather it is the canonical set of unnamed elements, as in "the set of 5 elements," for example.+Effectively, it is a type that captures integers that fall into the range of zero to ``(n - 1)`` where+``n`` is the argument used to instantiate the ``Fin`` type.+For example, ``Fin 5`` can be thought of as the type of integers between 0 and 4.++Let us look at the constructors in greater detail.++``FZ`` is the zeroth element of a finite set with ``S k`` elements;+``FS n`` is the ``n+1``\ th element of a finite set with ``S k``+elements. ``Fin`` is indexed by a ``Nat``, which represents the number+of elements in the set. Since we can’t construct an element of an+empty set, neither constructor targets ``Fin Z``.++As mentioned above, a useful application of the ``Fin`` family is to+represent bounded natural numbers. Since the first ``n`` natural+numbers form a finite set of ``n`` elements, we can treat ``Fin n`` as+the set of integers greater than or equal to zero and less than ``n``.++For example, the following function which looks up an element in a+``Vect``, by a bounded index given as a ``Fin n``, is defined in the+prelude:++.. code-block:: idris++    index : Fin n -> Vect n a -> a+    index FZ     (x :: xs) = x+    index (FS k) (x :: xs) = index k xs++This function looks up a value at a given location in a vector. The+location is bounded by the length of the vector (``n`` in each case),+so there is no need for a run-time bounds check. The type checker+guarantees that the location is no larger than the length of the+vector, and of course no less than zero.++Note also that there is no case for ``Nil`` here. This is because it+is impossible. Since there is no element of ``Fin Z``, and the+location is a ``Fin n``, then ``n`` can not be ``Z``. As a result,+attempting to look up an element in an empty vector would give a+compile time type error, since it would force ``n`` to be ``Z``.++Implicit Arguments+------------------++Let us take a closer look at the type of ``index``:++.. code-block:: idris++    index : Fin n -> Vect n a -> a++It takes two arguments, an element of the finite set of ``n`` elements,+and a vector with ``n`` elements of type ``a``. But there are also two+names, ``n`` and ``a``, which are not declared explicitly. These are+*implicit* arguments to ``index``. We could also write the type of+``index`` as:++.. code-block:: idris++    index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a++Implicit arguments, given in braces ``{}`` in the type declaration,+are not given in applications of ``index``; their values can be+inferred from the types of the ``Fin n`` and ``Vect n a``+arguments. Any name beginning with a lower case letter which appears+as a parameter or index in a+type declaration, which is not applied to any arguments, will+*always* be automatically+bound as an implicit argument. Implicit arguments can still be given+explicitly in applications, using ``{a=value}`` and ``{n=value}``, for+example:++.. code-block:: idris++    index {a=Int} {n=2} FZ (2 :: 3 :: Nil)++In fact, any argument, implicit or explicit, may be given a name. We+could have declared the type of ``index`` as:++.. code-block:: idris++    index : (i:Fin n) -> (xs:Vect n a) -> a++It is a matter of taste whether you want to do this — sometimes it can+help document a function by making the purpose of an argument more+clear.++Furthermore, ``{}`` can be used to pattern match on the left hand side, i.e.+``{var = pat}`` gets an implicit variable and attempts to pattern match on "pat";+For example :++.. code-block:: idris++    isEmpty : Vect n a -> Bool+    isEmpty {n = Z} _   = True+    isEmpty {n = S k} _ = False++“``using``” notation+--------------------++Sometimes it is useful to provide types of implicit arguments,+particularly where there is a dependency ordering, or where the+implicit arguments themselves have dependencies. For example, we may+wish to state the types of the implicit arguments in the following+definition, which defines a predicate on vectors (this is also defined+in ``Data.Vect``, under the name ``Elem``):++.. code-block:: idris++    data IsElem : a -> Vect n a -> Type where+       Here :  {x:a} ->   {xs:Vect n a} -> IsElem x (x :: xs)+       There : {x,y:a} -> {xs:Vect n a} -> IsElem x xs -> IsElem x (y :: xs)++An instance of ``IsElem x xs`` states that ``x`` is an element of+``xs``.  We can construct such a predicate if the required element is+``Here``, at the head of the vector, or ``There``, in the tail of the+vector. For example:++.. code-block:: idris++    testVec : Vect 4 Int+    testVec = 3 :: 4 :: 5 :: 6 :: Nil++    inVect : IsElem 5 Main.testVec+    inVect = There (There Here)+++.. important:: Implicit Arguments and Scope++    Within the type signature the typechecker will treat all variables+    that start with an lowercase letter **and** are not applied to+    something else as an implicit variable. To get the above code+    example to compile you will need to provide a qualified name for+    ``testVec``. In the example above, we have assumed that the code+    lives within the ``Main`` module.+++If the same implicit arguments are being used a lot, it can make a+definition difficult to read. To avoid this problem, a ``using`` block+gives the types and ordering of any implicit arguments which can+appear within the block:++.. code-block:: idris++    using (x:a, y:a, xs:Vect n a)+      data IsElem : a -> Vect n a -> Type where+         Here  : IsElem x (x :: xs)+         There : IsElem x xs -> IsElem x (y :: xs)++++Note: Declaration Order and ``mutual`` blocks+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++In general, functions and data types must be defined before use, since+dependent types allow functions to appear as part of types, and type+checking can rely on how particular functions are defined (though this+is only true of total functions; see Section :ref:`sect-totality`)).+However, this restriction can be relaxed by using a ``mutual`` block,+which allows data types and functions to be defined simultaneously:++.. code-block:: idris++    mutual+      even : Nat -> Bool+      even Z = True+      even (S k) = odd k++      odd : Nat -> Bool+      odd Z = False+      odd (S k) = even k++In a ``mutual`` block, first all of the type declarations are added,+then the function bodies. As a result, none of the function types can+depend on the reduction behaviour of any of the functions in the+block.++I/O+===++Computer programs are of little use if they do not interact with the+user or the system in some way. The difficulty in a pure language such+as Idris — that is, a language where expressions do not have+side-effects — is that I/O is inherently side-effecting. Therefore in+Idris, such interactions are encapsulated in the type ``IO``:++.. code-block:: idris++    data IO a -- IO operation returning a value of type a++We’ll leave the definition of ``IO`` abstract, but effectively it+describes what the I/O operations to be executed are, rather than how+to execute them. The resulting operations are executed externally, by+the run-time system. We’ve already seen one IO program:++.. code-block:: idris++    main : IO ()+    main = putStrLn "Hello world"++The type of ``putStrLn`` explains that it takes a string, and returns+an element of the unit type ``()`` via an I/O action. There is a+variant ``putStr`` which outputs a string without a newline:++.. code-block:: idris++    putStrLn : String -> IO ()+    putStr   : String -> IO ()++We can also read strings from user input:++.. code-block:: idris++    getLine : IO String++A number of other I/O operations are defined in the prelude, for+example for reading and writing files, including:++.. code-block:: idris++    data File -- abstract+    data Mode = Read | Write | ReadWrite++    openFile : (f : String) -> (m : Mode) -> IO (Either FileError File)+    closeFile : File -> IO ()++    fGetLine : (h : File) -> IO (Either FileError String)+    fPutStr : (h : File) -> (str : String) -> IO (Either FileError ())+    fEOF : File -> IO Bool++Note that several of these return ``Either``, since they may fail.++.. _sect-do:++“``do``” notation+=================++I/O programs will typically need to sequence actions, feeding the+output of one computation into the input of the next. ``IO`` is an+abstract type, however, so we can’t access the result of a computation+directly.  Instead, we sequence operations with ``do`` notation:++.. code-block:: idris++    greet : IO ()+    greet = do putStr "What is your name? "+               name <- getLine+               putStrLn ("Hello " ++ name)++The syntax ``x <- iovalue`` executes the I/O operation ``iovalue``, of+type ``IO a``, and puts the result, of type ``a`` into the variable+``x``. In this case, ``getLine`` returns an ``IO String``, so ``name``+has type ``String``. Indentation is significant — each statement in+the do block must begin in the same column. The ``return`` operation+allows us to inject a value directly into an IO operation:++.. code-block:: idris++    return : a -> IO a++As we will see later, ``do`` notation is more general than this, and+can be overloaded.++.. _sect-lazy:++Laziness+========++Normally, arguments to functions are evaluated before the function+itself (that is, Idris uses *eager* evaluation). However, this is+not always the best approach. Consider the following function:++.. code-block:: idris++    ifThenElse : Bool -> a -> a -> a;+    ifThenElse True  t e = t;+    ifThenElse False t e = e;++This function uses one of the ``t`` or ``e`` arguments, but not both+(in fact, this is used to implement the ``if...then...else`` construct+as we will see later. We would prefer if *only* the argument which was+used was evaluated. To achieve this, Idris provides a ``Lazy``+data type, which allows evaluation to be suspended:++.. code-block:: idris++    data Lazy : Type -> Type where+         Delay : (val : a) -> Lazy a++    Force : Lazy a -> a++A value of type ``Lazy a`` is unevaluated until it is forced by+``Force``. The Idris type checker knows about the ``Lazy`` type,+and inserts conversions where necessary between ``Lazy a`` and ``a``,+and vice versa. We can therefore write ``ifThenElse`` as follows,+without any explicit use of ``Force`` or ``Delay``:++.. code-block:: idris++    ifThenElse : Bool -> Lazy a -> Lazy a -> a;+    ifThenElse True  t e = t;+    ifThenElse False t e = e;++Codata Types+============++Codata types are like regular data types, except that they allow for us to+define infinite data structures.  More precisely, for a type ``T``, each of its+constructor arguments of type ``T`` are transformed into a coinductive parameter+``Inf T``. This makes each of the ``T`` arguments lazy, and allows infinite data+structures of type ``T`` to be built. One example of a codata type is Stream,+which is defined as follows.++.. code-block:: idris++    codata Stream : Type -> Type where+      (::) : (e : a) -> Stream a -> Stream a++This gets translated into the following by the compiler.++.. code-block:: idris++    data Stream : Type -> Type where+      (::) : (e : a) -> Inf (Stream a) -> Stream a++The following is an example of how the codata type ``Stream`` can be used to+form an infinite data structure. In this case we are creating an infinite stream+of ones.++.. code-block:: idris++    ones :: Stream Nat+    ones = 1 :: ones++It is important to note that codata does not allow the creation of infinite+mutually recursive data structures. For example the following will create an+infinite loop and cause a stack overflow.++.. code-block:: idris++    mutual+      codata Blue a = B a (Red a)+      codata Red a = R a (Blue a)++    mutual+      blue : Blue Nat+      blue = B 1 red++      red : Red Nat+      red = R 1 blue++    mutual+      findB : (a -> Bool) -> Blue a -> a+      findB f (B x r) = if f x then x else findR f r++      findR : (a -> Bool) -> Red a -> a+      findR f (R x b) = if f x then x else findB f b++    main : IO ()+    main = do printLn $ findB (== 1) blue++To fix this we must add explicit ``Inf`` declarations to the constructor+parameter types, since codata will not add it to constructor parameters of a+**different** type from the one being defined. For example, the following+outputs "1".++.. code-block:: idris++    mutual+      data Blue : Type -> Type where+       B : a -> Inf (Red a) -> Blue a++      data Red : Type -> Type where+       R : a -> Inf (Blue a) -> Red a++    mutual+      blue : Blue Nat+      blue = B 1 red++      red : Red Nat+      red = R 1 blue++    mutual+      findB : (a -> Bool) -> Blue a -> a+      findB f (B x r) = if f x then x else findR f r++      findR : (a -> Bool) -> Red a -> a+      findR f (R x b) = if f x then x else findB f b++    main : IO ()+    main = do printLn $ findB (== 1) blue++Useful Data Types+=================++Idris includes a number of useful data types and library functions+(see the ``libs/`` directory in the distribution). This chapter+describes a few of these. The functions described here are imported+automatically by every Idris program, as part of ``Prelude.idr``.++``List`` and ``Vect``+---------------------++We have already seen the ``List`` and ``Vect`` data types:++.. code-block:: idris++    data List a = Nil | (::) a (List a)++    data Vect : Nat -> Type -> Type where+       Nil  : Vect Z a+       (::) : a -> Vect k a -> Vect (S k) a++Note that the constructor names are the same for each — constructor+names (in fact, names in general) can be overloaded, provided that+they are declared in different namespaces (see Section+:ref:`sect-namespaces`), and will typically be resolved according to+their type. As syntactic sugar, any type with the constructor names+``Nil`` and ``::`` can be written in list form. For example:++-  ``[]`` means ``Nil``++-  ``[1,2,3]`` means ``1 :: 2 :: 3 :: Nil``++The library also defines a number of functions for manipulating these+types. ``map`` is overloaded both for ``List`` and ``Vect`` and+applies a function to every element of the list or vector.++.. code-block:: idris++    map : (a -> b) -> List a -> List b+    map f []        = []+    map f (x :: xs) = f x :: map f xs++    map : (a -> b) -> Vect n a -> Vect n b+    map f []        = []+    map f (x :: xs) = f x :: map f xs++For example, given the following vector of integers, and a function to+double an integer:++.. code-block:: idris++    intVec : Vect 5 Int+    intVec = [1, 2, 3, 4, 5]++    double : Int -> Int+    double x = x * 2++the function ``map`` can be used as follows to double every element in+the vector:++::++    *usefultypes> show (map double intVec)+    "[2, 4, 6, 8, 10]" : String++For more details of the functions available on ``List`` and+``Vect``, look in the library files:++-  ``libs/prelude/Prelude/List.idr``++-  ``libs/base/Data/List.idr``++-  ``libs/base/Data/Vect.idr``++-  ``libs/base/Data/VectType.idr``++Functions include filtering, appending, reversing, and so on. Also+remember that Idris is still in development, so if you don’t see+the function you need, please feel free to add it and submit a patch!++Aside: Anonymous functions and operator sections+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++There are actually neater ways to write the above expression. One way+would be to use an anonymous function:++::++    *usefultypes> show (map (\x => x * 2) intVec)+    "[2, 4, 6, 8, 10]" : String++The notation ``\x => val`` constructs an anonymous function which takes+one argument, ``x`` and returns the expression ``val``. Anonymous+functions may take several arguments, separated by commas,+e.g. ``\x, y, z => val``. Arguments may also be given explicit types,+e.g. ``\x : Int => x * 2``, and can pattern match,+e.g. ``\(x, y) => x + y``. We could also use an operator section:++::++    *usefultypes> show (map (* 2) intVec)+    "[2, 4, 6, 8, 10]" : String++``(*2)`` is shorthand for a function which multiplies a number+by 2. It expands to ``\x => x * 2``. Similarly, ``(2*)`` would expand+to ``\x => 2 * x``.++Maybe+-----++``Maybe`` describes an optional value. Either there is a value of the+given type, or there isn’t:++.. code-block:: idris++    data Maybe a = Just a | Nothing++``Maybe`` is one way of giving a type to an operation that may+fail. For example, looking something up in a ``List`` (rather than a+vector) may result in an out of bounds error:++.. code-block:: idris++    list_lookup : Nat -> List a -> Maybe a+    list_lookup _     Nil         = Nothing+    list_lookup Z     (x :: xs) = Just x+    list_lookup (S k) (x :: xs) = list_lookup k xs++The ``maybe`` function is used to process values of type ``Maybe``,+either by applying a function to the value, if there is one, or by+providing a default value:++.. code-block:: idris++    maybe : Lazy b -> Lazy (a -> b) -> Maybe a -> b++Note that the types of the first two arguments are wrapped in+``Lazy``. Since only one of the two arguments will actually be used,+we mark them as ``Lazy`` in case they are large expressions where it+would be wasteful to compute and then discard them.++Tuples+------++Values can be paired with the following built-in data type:++.. code-block:: idris++    data Pair a b = MkPair a b++As syntactic sugar, we can write ``(a, b)`` which, according to+context, means either ``Pair a b`` or ``MkPair a b``. Tuples can+contain an arbitrary number of values, represented as nested pairs:++.. code-block:: idris++    fred : (String, Int)+    fred = ("Fred", 42)++    jim : (String, Int, String)+    jim = ("Jim", 25, "Cambridge")++::++    *usefultypes> fst jim+    "Jim" : String+    *usefultypes> snd jim+    (25, "Cambridge") : (Int, String)+    *usefultypes> jim == ("Jim", (25, "Cambridge"))+    True : Bool++Dependent Pairs+---------------++Dependent pairs allow the type of the second element of a pair to depend+on the value of the first element. Traditionally, these are referred to+as “sigma types”:++.. code-block:: idris++    data DPair : (a : Type) -> (P : a -> Type) -> Type where+       MkDPair : {P : a -> Type} -> (x : a) -> P x -> DPair a P++Again, there is syntactic sugar for this. ``(a : A ** P)`` is the type+of a pair of A and P, where the name ``a`` can occur inside ``P``.+``( a ** p )`` constructs a value of this type. For example, we can+pair a number with a ``Vect`` of a particular length.++.. code-block:: idris++    vec : (n : Nat ** Vect n Int)+    vec = (2 ** [3, 4])++If you like, you can write it out the long way, the two are precisely+equivalent.++.. code-block:: idris++    vec : DPair Nat (\n => Vect n Int)+    vec = MkDPair 2 [3, 4]++The type checker could of course infer the value of the first element+from the length of the vector. We can write an underscore ``_`` in+place of values which we expect the type checker to fill in, so the+above definition could also be written as:++.. code-block:: idris++    vec : (n : Nat ** Vect n Int)+    vec = (_ ** [3, 4])++We might also prefer to omit the type of the first element of the+pair, since, again, it can be inferred:++.. code-block:: idris++    vec : (n ** Vect n Int)+    vec = (_ ** [3, 4])++One use for dependent pairs is to return values of dependent types+where the index is not necessarily known in advance. For example, if+we filter elements out of a ``Vect`` according to some predicate, we+will not know in advance what the length of the resulting vector will+be:++.. code-block:: idris++    filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)++If the ``Vect`` is empty, the result is easy:++.. code-block:: idris++    filter p Nil = (_ ** [])++In the ``::`` case, we need to inspect the result of a recursive call+to ``filter`` to extract the length and the vector from the result. To+do this, we use ``with`` notation, which allows pattern matching on+intermediate values:++.. code-block:: idris++    filter p (x :: xs) with (filter p xs)+      | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )++We will see more on ``with`` notation later.+++Records+-------++*Records* are data types which collect several values (the record's+*fields*) together. Idris provides syntax for defining records and+automatically generating field access and update functions. Unlike+the syntax used for data structures, records in Idris follow a+different syntax to that seen with Haskell. For example, we can+represent a person's name and age in a record:++.. code-block:: idris++    record Person where+        constructor MkPerson+        firstName, middleName, lastName : String+        age : Int++    fred : Person+    fred = MkPerson "Fred" "Joe" "Bloggs" 30+++The constructor name is provided using the ``constructor`` keyword,+and the *fields* are then given which are in an indented block+following the `where` keyword (here, ``firstName``, ``middleName``,+``lastName``, and ``age``). You can declare multiple fields on a+single line, provided that they have the same type.  The field names+can be used to access the field values:++::++    *record> firstName fred+    "Fred" : String+    *record> age fred+    30 : Int+    *record> :t firstName+    firstName : Person -> String++We can also use the field names to update a record (or, more+precisely, produce a copy of the record with the given fields+updated):++.. code-block:: bash++    *record> record { firstName = "Jim" } fred+    MkPerson "Jim" "Joe" "Bloggs" 30 : Person+    *record> record { firstName = "Jim", age $= (+ 1) } fred+    MkPerson "Jim" "Joe" "Bloggs" 31 : Person++The syntax ``record { field = val, ... }`` generates a function which+updates the given fields in a record. ``=`` assigns a new value to a field,+and ``$=`` applies a function to update its value.++Each record is defined in its own namespace, which means that field names+can be reused in multiple records.++Records, and fields within records, can have dependent types. Updates+are allowed to change the type of a field, provided that the result is+well-typed.++.. code-block:: idris++    record Class where+        constructor ClassInfo+        students : Vect n Person+        className : String++It is safe to update the ``students`` field to a vector of a different+length because it will not affect the type of the record:++.. code-block:: idris++    addStudent : Person -> Class -> Class+    addStudent p c = record { students = p :: students c } c++::++    *record> addStudent fred (ClassInfo [] "CS")+    ClassInfo [MkPerson "Fred" "Joe" "Bloggs" 30] "CS" : Class+++Nested record update+~~~~~~~~~~~~~~~~~~~~++Idris also provides a convenient syntax for accessing and updating+nested records. For example, if a field is accessible with the+expression ``c (b (a x))``, it can be updated using the following+syntax:++.. code-block:: idris++    record { a->b->c = val } x++This returns a new record, with the field accessed by the path+``a->b->c`` set to ``val``. The syntax is first class, i.e.  ``record {+a->b->c = val }`` itself has a function type. Symmetrically, the field+can also be accessed with the following syntax:++.. code-block:: idris++    record { a->b->c } x+++Dependent Records+-----------------++Records can also be dependent on values. Records *parameters*, which+are not subject to field updates. The parameters appear as arguments+to the resulting type, and are written following the record type+name. For example, a pair type could be defined as follows:++.. code-block:: idris++    record Prod a b where+        constructor Times+        fst : a+        snd : b+++Using the class record from the original introduction to records.  The+size of the class can be restricted using a ``Vect`` and the size+promoted to the type level by parameterising the record with the size.+For example:+++.. code-block:: idris++    record SizedClass (size : Nat) where+        constructor SizedClassInfo+        students : Vect size Person+        className : String++**Note** that it is no longer possible to use the ``addStudent``+function from earlier, since that would change the size of the class. A+function to add a student must now specify in the type that the+size of the class has been increased by one. As the size is specified+using natural numbers, the new value can be incremented using the+``S`` constructor.++.. code-block:: idris++    addStudent : Person -> SizedClass n -> SizedClass (S n)+    addStudent p c =  SizedClassInfo (p :: students c) (className c)++.. _sect-more-expr:++More Expressions+================++``let`` bindings+----------------++Intermediate values can be calculated using ``let`` bindings:++.. code-block:: idris++   mirror : List a -> List a+   mirror xs = let xs' = reverse xs in+                   xs ++ xs'++We can do simple pattern matching in ``let`` bindings too. For+example, we can extract fields from a record as follows, as well as by+pattern matching at the top level:++.. code-block:: idris++    data Person = MkPerson String Int++    showPerson : Person -> String+    showPerson p = let MkPerson name age = p in+                       name ++ " is " ++ show age ++ " years old"++List comprehensions+-------------------++Idris provides *comprehension* notation as a convenient shorthand+for building lists. The general form is:++::++    [ expression | qualifiers ]++This generates the list of values produced by evaluating the+``expression``, according to the conditions given by the comma+separated ``qualifiers``. For example, we can build a list of+Pythagorean triples as follows:++.. code-block:: idris++    pythag : Int -> List (Int, Int, Int)+    pythag n = [ (x, y, z) | z <- [1..n], y <- [1..z], x <- [1..y],+                             x*x + y*y == z*z ]++The ``[a..b]`` notation is another shorthand which builds a list of+numbers between ``a`` and ``b``. Alternatively ``[a,b..c]`` builds a+list of numbers between ``a`` and ``c`` with the increment specified+by the difference between ``a`` and ``b``. This works for type ``Nat``,+``Int`` and ``Integer``, using the ``enumFromTo`` and ``enumFromThenTo``+function from the prelude.++``case`` expressions+--------------------++Another way of inspecting intermediate values of *simple* types is to+use a ``case`` expression. The following function, for example, splits+a string into two at a given character:++.. code-block:: idris++    splitAt : Char -> String -> (String, String)+    splitAt c x = case break (== c) x of+                      (x, y) => (x, strTail y)++``break`` is a library function which breaks a string into a pair of+strings at the point where the given function returns true. We then+deconstruct the pair it returns, and remove the first character of the+second string.++A ``case`` expression can match several cases, for example, to inspect+an intermediate value of type ``Maybe a``. Recall ``list_lookup``+which looks up an index in a list, returning ``Nothing`` if the index+is out of bounds. We can use this to write ``lookup_default``, which+looks up an index and returns a default value if the index is out of+bounds:++.. code-block:: idris++    lookup_default : Nat -> List a -> a -> a+    lookup_default i xs def = case list_lookup i xs of+                                  Nothing => def+                                  Just x => x++If the index is in bounds, we get the value at that index, otherwise+we get a default value:++::++    *usefultypes> lookup_default 2 [3,4,5,6] (-1)+    5 : Integer+    *usefultypes> lookup_default 4 [3,4,5,6] (-1)+    -1 : Integer++**Restrictions:** The ``case`` construct is intended for simple+analysis of intermediate expressions to avoid the need to write+auxiliary functions, and is also used internally to implement pattern+matching ``let`` and lambda bindings. It will *only* work if:++- Each branch *matches* a value of the same type, and *returns* a+  value of the same type.++- The type of the result is "known". i.e. the type of the expression+  can be determined *without* type checking the ``case``-expression+  itself.++Totality+========++A *total* function is a function that terminates for all possible+inputs, or one that is guaranteed to produce some output before making+a recursive call. For example, Idris' ``head`` function is total for+all lists:++::++    Idris> :t Prelude.List.head+    head : (l : List a) -> {auto ok : NonEmpty l} -> a++The ``{auto ok : NonEmpty l}`` tells us that Idris won't compile if we+try to call ``head`` on an empty list. The implementation is as follows:++.. code-block:: idris++    ||| Get the first element of a non-empty list+    ||| @ ok proof that the list is non-empty+    head : (l : List a) -> {auto ok : NonEmpty l} -> a+    head []      {ok=IsNonEmpty} impossible+    head (x::xs) {ok=p}    = x++(Note that this implementation is in contrast to Haskell's ``head``,+which is  *not* total and will fail at runtime rather than compile time.)+The following Idris code will compile:++.. code-block:: idris++    module Main++    main : IO ()+    main = do+      let x : Integer = head [1,2,3]+      print x++And will print ``1``. However, the same code with ``head []`` won't compile:++::++    test.idr:5:26:When checking right hand side of main with expected type+        IO ()++    When checking argument ok to function Prelude.List.head:+          Can't find a value of type+                  NonEmpty []++We can't bind and print ``x`` because ``head []`` doesn't type check.++However, we might imagine a function, ``unsafeHead``, that is identical to+Idris' ``head`` function except that it is *not* total: it will error out+at runtime if called on an empty list. (This is similar to the behavior of+Haskell's ``head`` function.) ``unsafeHead`` might look like this:++.. code-block:: idris++    -- Unsafe head example!+    unsafeHead : List a -> a+    unsafeHead (x::xs) = x++And although it typechecks and compiles, it will not reduce (that is, evaluation+of the function will cause it to change):++::++    unsafe> the Integer $ unsafeHead [1, 2, 3]+    1 : Integer+    unsafe> the Integer $ unsafeHead []+    unsafeHead [] : Integer++Functions that are not total are known as *partial functions*. As+mentioned in the note about ``mutual`` blocks, non-total definitions+aren't reduced when type checking because they are not well-defined+for all possible inputs.
+ docs/tutorial/views.rst view
@@ -0,0 +1,98 @@+.. _sec-views:++*****************************+Views and the “``with``” rule+*****************************++Dependent pattern matching+==========================++Since types can depend on values, the form of some arguments can be+determined by the value of others. For example, if we were to write+down the implicit length arguments to ``(++)``, we’d see that the form+of the length argument was determined by whether the vector was empty+or not:++.. code-block:: idris++    (++) : Vect n a -> Vect m a -> Vect (n + m) a+    (++) {n=Z}   []        ys = ys+    (++) {n=S k} (x :: xs) ys = x :: xs ++ ys++If ``n`` was a successor in the ``[]`` case, or zero in the ``::``+case, the definition would not be well typed.++.. _sect-nattobin:++The ``with`` rule — matching intermediate values+================================================++Very often, we need to match on the result of an intermediate+computation. Idris provides a construct for this, the ``with``+rule, inspired by views in ``Epigram`` [1]_, which takes account of+the fact that matching on a value in a dependently typed language can+affect what we know about the forms of other values. In its simplest+form, the ``with`` rule adds another argument to the function being+defined, e.g. we have already seen a vector filter function, defined+as follows:++.. code-block:: idris++    filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)+    filter p [] = ( _ ** [] )+    filter p (x :: xs) with (filter p xs)+      | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )++Here, the ``with`` clause allows us to deconstruct the result of+``filter p xs``. Effectively, it adds this value as an extra argument,+which we place after the vertical bar.++If the intermediate computation itself has a dependent type, then the+result can affect the forms of other arguments — we can learn the form+of one value by testing another. For example, a ``Nat`` is either even+or odd. If it’s even it will be the sum of two equal ``Nat``.+Otherwise, it is the sum of two equal ``Nat`` plus one:++.. code-block:: idris++    data Parity : Nat -> Type where+       Even : Parity (n + n)+       Odd  : Parity (S (n + n))++We say ``Parity`` is a *view* of ``Nat``. It has a *covering function*+which tests whether it is even or odd and constructs the predicate+accordingly.++.. code-block:: idris++    parity : (n:Nat) -> Parity n++We’ll come back to the definition of ``parity`` shortly. We can use it+to write a function which converts a natural number to a list of+binary digits (least significant first) as follows, using the ``with``+rule:++.. code-block:: idris++    natToBin : Nat -> List Bool+    natToBin Z = Nil+    natToBin k with (parity k)+       natToBin (j + j)     | Even = False :: natToBin j+       natToBin (S (j + j)) | Odd  = True  :: natToBin j++The value of the result of ``parity k`` affects the form of ``k``,+because the result of ``parity k`` depends on ``k``. So, as well as+the patterns for the result of the intermediate computation (``Even``+and ``odd``) right of the ``|``, we also write how the results+affect the other patterns left of the ``|``. Note that there is+a function in the patterns (``+``) and repeated occurrences of+``j``—this is allowed because another argument has determined the form+of these patterns.++We will return to this function in Section :ref:`sect-provisional` to+complete the definition of ``parity``.++.. [1] Conor McBride and James McKinna. 2004. The view from the+       left. J. Funct. Program. 14, 1 (January 2004),+       69-111. DOI=10.1017/S0956796803004829+       http://dx.doi.org/10.1017/S0956796803004829ñ
+ icons/idris-128x128.png view

binary file changed (absent → 3755 bytes)

+ icons/idris-256x256.png view

binary file changed (absent → 9186 bytes)

+ icons/idris-48x48.png view

binary file changed (absent → 1429 bytes)

+ icons/idris-512x512.png view

binary file changed (absent → 25396 bytes)

+ icons/idris-64x64.png view

binary file changed (absent → 1735 bytes)

+ icons/text-x-idris.svg view
@@ -0,0 +1,85 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with VectorDraw -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="311.90765"+   height="570.46472"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="text-x-idris.svg">+  <metadata+     id="metadata11">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <defs+     id="defs9" />+  <sodipodi:namedview+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1"+     objecttolerance="10"+     gridtolerance="10"+     guidetolerance="10"+     inkscape:pageopacity="0"+     inkscape:pageshadow="2"+     inkscape:window-width="1918"+     inkscape:window-height="1034"+     id="namedview7"+     showgrid="false"+     inkscape:zoom="0.56123662"+     inkscape:cx="54.151709"+     inkscape:cy="-28.476384"+     inkscape:window-x="1920"+     inkscape:window-y="25"+     inkscape:window-maximized="0"+     inkscape:current-layer=""+     fit-margin-top="0"+     fit-margin-left="1.2"+     fit-margin-right="0"+     fit-margin-bottom="0" />+  <g+     inkscape:label=""+     inkscape:groupmode="layer"+     id=""+     transform="translate(1.407669,-0.379032)">+    <g+       id="g3353"+       transform="translate(22,0)">+      <path+         inkscape:connector-curvature="0"+         id="path3345"+         d="M 79.07716,85.235105 C 152.15731,107.3516 170.85211,125.57188 196.54561,191.60466 191.5621,111.08837 159.33816,77.523083 79.07716,85.235105 c 18.82716,-67.890093 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         inkscape:connector-curvature="0"+         id="path3343"+         d="M -22.207669,211.87449 C 25.234912,226.48437 80.323859,238.15903 100.68023,328.79942 109.08411,215.72166 55.546121,209.96088 -22.207669,211.87449 c 90.648682,-302.180016 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         inkscape:connector-curvature="0"+         id="path3341"+         d="M 9.8483347,139.76992 C 81.136615,154.50235 126.58014,173.85823 153.14004,265.85432 159.23348,147.17442 94.093917,135.25771 9.8483347,139.76992 c 78.3893863,-131.1880199 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         id="path5"+         d="M 103.33025,0.379032 C 492.35181,254.04105 16.917801,258.5227 120.33008,553.01685 c 0,0 61.21588,17.8269 61.21588,17.8269 C 12.902722,342.22024 556.89801,224.698 103.33025,0.379032 c 0,0 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none"+         inkscape:connector-curvature="0" />+    </g>+  </g>+</svg>
+ icons/x-idris-bytecode.xml view
@@ -0,0 +1,4 @@+<?xml version="1.0" encoding="utf-8"?>+<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="application/x-idris-bytecode">+  <glob pattern="*.ibc"/>+</mime-type>
+ icons/x-idris-literate.xml view
@@ -0,0 +1,4 @@+<?xml version="1.0" encoding="utf-8"?>+<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/x-idris-literate">+  <glob pattern="*.lidr"/>+</mime-type>
+ icons/x-idris.xml view
@@ -0,0 +1,4 @@+<?xml version="1.0" encoding="utf-8"?>+<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/x-idris">+  <glob pattern="*.idr"/>+</mime-type>
idris.cabal view
@@ -1,5 +1,5 @@ Name:           idris-Version:        0.12.2+Version:        0.12.3 License:        BSD3 License-file:   LICENSE Author:         Edwin Brady@@ -44,6 +44,8 @@  Build-type:     Custom +Tested-With:    GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1+ Data-files:            idrisdoc/styles.css                        jsrts/Runtime-browser.js                        jsrts/Runtime-common.js@@ -87,849 +89,9 @@                        samples/misc/*.lidr                        samples/tutorial/*.idr +-- extra-source-files is generated by Setup.hs using `git --ls-files`. Extra-source-files:-                       Makefile-                       config.mk-                       stack.yaml-                       HLint.hs-                       man/idris.1 -                       rts/*.c-                       rts/*.h-                       rts/arduino/*.c-                       rts/windows/*.c-                       rts/Makefile--                       libs/Makefile--                       libs/prelude/prelude.ipkg-                       libs/prelude/Prelude/*.idr-                       libs/prelude/Decidable/*.idr-                       libs/prelude/Language/*.idr-                       libs/prelude/Language/Reflection/*.idr-                       libs/prelude/Makefile-                       libs/prelude/*.idr--                       libs/base/base.ipkg-                       libs/base/*.idr-                       libs/base/Control/*.idr-                       libs/base/Control/Monad/*.idr-                       libs/base/Data/*.idr-                       libs/base/Data/Nat/*.idr-                       libs/base/Data/Primitives/*.idr-                       libs/base/Data/List/*.idr-                       libs/base/Data/Vect/*.idr-                       libs/base/Data/String/*.idr-                       libs/base/Debug/*.idr-                       libs/base/Language/Reflection/*.idr-                       libs/base/Makefile-                       libs/base/System/*.idr-                       libs/base/System/Concurrency/*.idr-                       libs/base/Syntax/*.idr--                       libs/contrib/contrib.ipkg-                       libs/contrib/Makefile-                       libs/contrib/*.idr-                       libs/contrib/CFFI/*.idr-                       libs/contrib/Classes/*.idr-                       libs/contrib/Control/*.idr-                       libs/contrib/Control/Isomorphism/*.idr-                       libs/contrib/Control/Algebra/*.idr-                       libs/contrib/Data/*.idr-                       libs/contrib/Data/Nat/*.idr-                       libs/contrib/Data/Nat/DivMod/*.idr-                       libs/contrib/Data/Matrix/*.idr-                       libs/contrib/Decidable/*.idr-                       libs/contrib/Network/*.idr-                       libs/contrib/System/Concurrency/*.idr--                       libs/effects/Makefile-                       libs/effects/effects.ipkg-                       libs/effects/Effect/*.idr-                       libs/effects/Effect/Logging/*.idr-                       libs/effects/*.idr--                       libs/pruviloj/Makefile-                       libs/pruviloj/pruviloj.ipkg-                       libs/pruviloj/*.idr-                       libs/pruviloj/Pruviloj/*.idr-                       libs/pruviloj/Pruviloj/Derive/*.idr-                       libs/pruviloj/Pruviloj/Internals/*.idr--                       test/TestRun.hs-                       test/TestData.hs--                       test/regression001/run-                       test/regression001/expected-                       test/regression001/*.idr-                       test/regression001/*.lidr--                       test/reg002/run-                       test/reg002/*.idr-                       test/reg002/expected-                       test/reg003/run-                       test/reg003/*.idr-                       test/reg003/expected-                       test/reg004/run-                       test/reg004/*.idr-                       test/reg004/expected-                       test/reg005/run-                       test/reg005/*.idr-                       test/reg005/expected-                       test/reg006/run-                       test/reg006/*.idr-                       test/reg006/expected-                       test/reg007/run-                       test/reg007/*.lidr-                       test/reg007/expected-                       test/reg010/run-                       test/reg010/*.idr-                       test/reg010/expected-                       test/reg013/run-                       test/reg013/*.idr-                       test/reg013/expected-                       test/reg016/run-                       test/reg016/*.idr-                       test/reg016/expected-                       test/reg017/run-                       test/reg017/*.idr-                       test/reg017/expected-                       test/reg018/run-                       test/reg018/*.idr-                       test/reg018/expected-                       test/reg020/run-                       test/reg020/*.idr-                       test/reg020/expected-                       test/reg023/run-                       test/reg023/*.idr-                       test/reg023/expected-                       test/reg024/run-                       test/reg024/*.idr-                       test/reg024/expected-                       test/reg025/run-                       test/reg025/*.idr-                       test/reg025/expected-                       test/reg027/run-                       test/reg027/*.idr-                       test/reg027/expected-                       test/reg028/run-                       test/reg028/*.idr-                       test/reg028/expected-                       test/reg029/run-                       test/reg029/*.idr-                       test/reg029/expected-                       test/reg031/run-                       test/reg031/*.idr-                       test/reg031/expected-                       test/reg032/run-                       test/reg032/*.idr-                       test/reg032/expected-                       test/reg034/run-                       test/reg034/*.idr-                       test/reg034/expected-                       test/reg035/run-                       test/reg035/*.idr-                       test/reg035/*.lidr-                       test/reg035/expected-                       test/reg039/run-                       test/reg039/*.idr-                       test/reg039/expected-                       test/reg040/run-                       test/reg040/*.idr-                       test/reg040/expected-                       test/reg041/run-                       test/reg041/*.idr-                       test/reg041/expected-                       test/reg042/run-                       test/reg042/*.idr-                       test/reg042/expected-                       test/reg044/run-                       test/reg044/*.idr-                       test/reg044/expected-                       test/reg045/run-                       test/reg045/*.idr-                       test/reg045/expected-                       test/reg048/run-                       test/reg048/*.idr-                       test/reg048/expected-                       test/reg049/run-                       test/reg049/*.idr-                       test/reg049/expected-                       test/reg050/run-                       test/reg050/*.idr-                       test/reg050/expected-                       test/reg051-disabled/run-                       test/reg051-disabled/*.idr-                       test/reg051-disabled/expected-                       test/reg052/run-                       test/reg052/*.idr-                       test/reg052/expected-                       test/reg054/run-                       test/reg054/*.idr-                       test/reg054/expected-                       test/reg055/run-                       test/reg055/*.idr-                       test/reg055/expected-                       test/reg056/run-                       test/reg056/*.idr-                       test/reg056/expected-                       test/reg067/run-                       test/reg067/*.idr-                       test/reg067/expected-                       test/reg068/run-                       test/reg068/*.idr-                       test/reg068/expected-                       test/reg069/run-                       test/reg069/*.idr-                       test/reg069/expected-                       test/reg070/run-                       test/reg070/*.idr-                       test/reg070/expected-                       test/reg072/run-                       test/reg072/*.idr-                       test/reg072/expected-                       test/reg075/run-                       test/reg075/input-                       test/reg075/*.idr-                       test/reg075/expected--                       test/base001/Makefile-                       test/base001/base001.idr-                       test/base001/base001.ipkg-                       test/base001/exit1.c-                       test/base001/expected-                       test/base001/run-                       test/base001/sys.c-                       test/base001/sys.h--                       test/basic001/run-                       test/basic001/*.idr-                       test/basic001/expected-                       test/basic002/run-                       test/basic002/*.idr-                       test/basic002/expected-                       test/basic003/run-                       test/basic003/*.idr-                       test/basic003/expected-                       test/basic004/run-                       test/basic004/*.idr-                       test/basic004/expected-                       test/basic005/run-                       test/basic005/*.lidr-                       test/basic005/expected-                       test/basic006/run-                       test/basic006/*.idr-                       test/basic006/expected-                       test/basic007/run-                       test/basic007/*.idr-                       test/basic007/expected-                       test/basic008/run-                       test/basic008/*.idr-                       test/basic008/expected-                       test/basic009/run-                       test/basic009/*.idr-                       test/basic009/expected-                       test/basic009/B/*.idr-                       test/basic010/run-                       test/basic010/*.idr-                       test/basic010/expected-                       test/basic011/run-                       test/basic011/*.idr-                       test/basic011/expected-                       test/basic012/run-                       test/basic012/*.idr-                       test/basic012/expected-                       test/basic013/run-                       test/basic013/*.idr-                       test/basic013/expected-                       test/basic014/run-                       test/basic014/*.idr-                       test/basic014/expected-                       test/basic015/run-                       test/basic015/*.idr-                       test/basic015/expected-                       test/basic016/run-                       test/basic016/*.idr-                       test/basic016/expected-                       test/basic017/run-                       test/basic017/*.idr-                       test/basic017/expected-                       test/basic018/run-                       test/basic018/*.idr-                       test/basic018/expected--                       test/bignum001/run-                       test/bignum001/*.idr-                       test/bignum001/expected-                       test/bignum002/run-                       test/bignum002/*.idr-                       test/bignum002/expected--                       test/bounded001/run-                       test/bounded001/*.idr-                       test/bounded001/expected--                       test/corecords001/*.idr-                       test/corecords001/run-                       test/corecords001/expected-                       test/corecords002/*.idr-                       test/corecords002/run-                       test/corecords002/expected--                       test/directives001/*.idr-                       test/directives001/run-                       test/directives001/expected-                       test/directives002/*.idr-                       test/directives002/run-                       test/directives002/expected--                       test/delab001/*.idr-                       test/delab001/run-                       test/delab001/expected-                       test/delab001/input--                       test/disambig002/run-                       test/disambig002/*.idr-                       test/disambig002/expected--                       test/dsl001/run-                       test/dsl001/*.idr-                       test/dsl001/expected-                       test/dsl002/run-                       test/dsl002/test-                       test/dsl002/*.idr-                       test/dsl002/expected-                       test/dsl003/run-                       test/dsl003/*.idr-                       test/dsl003/expected-                       test/dsl004/run-                       test/dsl004/*.idr-                       test/dsl004/expected--                       test/effects001/run-                       test/effects001/*.idr-                       test/effects001/expected-                       test/effects001/testFile-                       test/effects002/run-                       test/effects002/*.idr-                       test/effects002/expected-                       test/effects003/run-                       test/effects003/*.idr-                       test/effects003/expected-                       test/effects003/input-                       test/effects004/run-                       test/effects004/*.idr-                       test/effects004/expected-                       test/effects004/input-                       test/effects005/run-                       test/effects005/*.idr-                       test/effects005/expected---                       test/error001/run-                       test/error001/*.idr-                       test/error001/expected-                       test/error002/run-                       test/error002/*.idr-                       test/error002/expected-                       test/error003/run-                       test/error003/*.idr-                       test/error003/expected-                       test/error004/run-                       test/error004/*.idr-                       test/error004/expected-                       test/error005/run-                       test/error005/*.idr-                       test/error005/expected-                       test/error006/run-                       test/error006/*.idr-                       test/error006/expected-                       test/error007/run-                       test/error007/*.idr-                       test/error007/expected-                       test/error008/run-                       test/error008/*.idr-                       test/error008/expected--                       test/ffi001/run-                       test/ffi001/*.idr-                       test/ffi001/expected-                       test/ffi002/run-                       test/ffi002/*.idr-                       test/ffi002/expected-                       test/ffi003/run-                       test/ffi003/*.idr-                       test/ffi003/expected-                       test/ffi003/input-                       test/ffi004/run-                       test/ffi004/*.idr-                       test/ffi004/theType-                       test/ffi004/theOtherType-                       test/ffi004/expected-                       test/ffi005/*.idr-                       test/ffi005/run-                       test/ffi005/expected-                       test/ffi006/*.idr-                       test/ffi006/*.c-                       test/ffi006/run-                       test/ffi006/expected-                       test/ffi007/*.idr-                       test/ffi007/*.c-                       test/ffi007/*.h-                       test/ffi007/run-                       test/ffi007/expected-                       test/ffi008/*.idr-                       test/ffi008/*.c-                       test/ffi008/*.h-                       test/ffi008/run-                       test/ffi008/expected--                       test/folding001/*.idr-                       test/folding001/run-                       test/folding001/expected--                       test/idrisdoc001/run-                       test/idrisdoc001/expected-                       test/idrisdoc001/*.idr-                       test/idrisdoc001/*.ipkg-                       test/idrisdoc002/run-                       test/idrisdoc002/expected-                       test/idrisdoc002/*.idr-                       test/idrisdoc002/*.ipkg-                       test/idrisdoc003/run-                       test/idrisdoc003/expected-                       test/idrisdoc003/*.idr-                       test/idrisdoc003/*.ipkg-                       test/idrisdoc004/run-                       test/idrisdoc004/expected-                       test/idrisdoc004/*.idr-                       test/idrisdoc004/*.ipkg-                       test/idrisdoc005/run-                       test/idrisdoc005/expected-                       test/idrisdoc005/*.idr-                       test/idrisdoc005/*.ipkg-                       test/idrisdoc006/run-                       test/idrisdoc006/expected-                       test/idrisdoc006/A/fully/Qualified/NAME.idr-                       test/idrisdoc006/*.idr-                       test/idrisdoc006/*.ipkg-                       test/idrisdoc007/run-                       test/idrisdoc007/expected-                       test/idrisdoc007/*.idr-                       test/idrisdoc007/*.ipkg-                       test/idrisdoc008/run-                       test/idrisdoc008/expected-                       test/idrisdoc008/*.idr-                       test/idrisdoc008/*.ipkg-                       test/idrisdoc009/run-                       test/idrisdoc009/expected-                       test/idrisdoc009/input-                       test/idrisdoc009/*.idr---                       test/interactive001/run-                       test/interactive001/input-                       test/interactive001/*.idr-                       test/interactive001/expected-                       test/interactive002/run-                       test/interactive002/input-                       test/interactive002/*.idr-                       test/interactive002/expected-                       test/interactive003/run-                       test/interactive003/input-                       test/interactive003/*.idr-                       test/interactive003/expected-                       test/interactive004/run-                       test/interactive004/input-                       test/interactive004/*.idr-                       test/interactive004/expected-                       test/interactive005/run-                       test/interactive005/input-                       test/interactive005/*.idr-                       test/interactive005/expected-                       test/interactive006/run-                       test/interactive006/input-                       test/interactive006/*.idr-                       test/interactive006/expected-                       test/interactive007/run-                       test/interactive007/input-                       test/interactive007/expected-                       test/interactive008/run-                       test/interactive008/input-                       test/interactive008/expected-                       test/interactive009/run-                       test/interactive009/input-                       test/interactive009/*.idr-                       test/interactive009/expected-                       test/interactive010/expected-                       test/interactive010/input-                       test/interactive010/run-                       test/interactive011/expected-                       test/interactive011/input-                       test/interactive011/run-                       test/interactive011/*.idr-                       test/interactive012/expected-                       test/interactive012/input-                       test/interactive012/run-                       test/interactive012/*.idr-                       test/interactive013/expected-                       test/interactive013/input-                       test/interactive013/run-                       test/interactive013/*.idr--                       test/interfaces001/*.idr-                       test/interfaces001/run-                       test/interfaces001/expected-                       test/interfaces001/input-                       test/interfaces002/*.idr-                       test/interfaces002/run-                       test/interfaces002/expected-                       test/interfaces003/*.idr-                       test/interfaces003/run-                       test/interfaces003/expected-                       test/interfaces004/*.idr-                       test/interfaces004/run-                       test/interfaces004/expected-                       test/interfaces005/*.idr-                       test/interfaces005/run-                       test/interfaces005/expected-                       test/interfaces006/*.idr-                       test/interfaces006/run-                       test/interfaces006/expected--                       test/io001/run-                       test/io001/*.idr-                       test/io001/expected-                       test/io002/run-                       test/io002/*.idr-                       test/io002/expected-                       test/io003/run-                       test/io003/*.idr-                       test/io003/expected--                       test/layout001/expected-                       test/layout001/*.idr-                       test/layout001/run--                       test/literate001/run-                       test/literate001/*.lidr-                       test/literate001/expected--                       test/meta001/run-                       test/meta001/*.idr-                       test/meta001/expected-                       test/meta002/run-                       test/meta002/*.idr-                       test/meta002/expected-                       test/meta003/run-                       test/meta003/*.idr-                       test/meta003/expected-                       test/meta004/run-                       test/meta004/*.idr-                       test/meta004/expected--                       test/prelude001/expected-                       test/prelude001/prelude001.idr-                       test/prelude001/run--                       test/primitives001/run-                       test/primitives001/*.idr-                       test/primitives001/expected-                       test/primitives001/input-                       test/primitives002/run-                       test/primitives002/expected-                       test/primitives003/run-                       test/primitives003/*.idr-                       test/primitives003/expected-                       test/primitives005/run-                       test/primitives005/*.idr-                       test/primitives005/expected--                       test/primitives006/run-                       test/primitives006/array.c-                       test/primitives006/array.h-                       test/primitives006/load-test.idr-                       test/primitives006/Data/Bytes.idr-                       test/primitives006/Data/ByteArray.idr-                       test/primitives006/expected--                       test/pkg001/run-                       test/pkg001/*.idr-                       test/pkg001/expected-                       test/pkg001/*.ipkg-                       test/pkg002/run-                       test/pkg002/*.idr-                       test/pkg002/expected-                       test/pkg002/*.ipkg-                       test/pkg003/run-                       test/pkg003/*.idr-                       test/pkg003/expected-                       test/pkg003/*.ipkg-                       test/pkg004/run-                       test/pkg004/*.idr-                       test/pkg004/expected-                       test/pkg004/*.ipkg-                       test/pkg005/run-                       test/pkg005/expected-                       test/pkg005/*.ipkg-                       test/pkg006/run-                       test/pkg006/expected-                       test/pkg006/*.ipkg--                       test/proof001/run-                       test/proof001/*.idr-                       test/proof001/expected-                       test/proof002/run-                       test/proof002/*.idr-                       test/proof002/expected-                       test/proof003/run-                       test/proof003/*.idr-                       test/proof003/expected-                       test/proof004/run-                       test/proof004/*.idr-                       test/proof004/expected-                       test/proof005/run-                       test/proof005/*.idr-                       test/proof005/expected-                       test/proof006/run-                       test/proof006/*.idr-                       test/proof006/expected-                       test/proof007/run-                       test/proof007/*.idr-                       test/proof007/expected-                       test/proof008/run-                       test/proof008/*.idr-                       test/proof008/expected-                       test/proof009/run-                       test/proof009/*.idr-                       test/proof009/expected-                       test/proof009/input-                       test/proof010/run-                       test/proof010/*.idr-                       test/proof010/expected-                       test/proof011/run-                       test/proof011/*.idr-                       test/proof011/expected--                       test/proofsearch001/run-                       test/proofsearch001/*.idr-                       test/proofsearch001/expected-                       test/proofsearch002/run-                       test/proofsearch002/*.idr-                       test/proofsearch002/expected-                       test/proofsearch003/run-                       test/proofsearch003/*.idr-                       test/proofsearch003/expected--                       test/pruviloj001/run-                       test/pruviloj001/*.idr-                       test/pruviloj001/expected--                       test/quasiquote001/run-                       test/quasiquote001/*.idr-                       test/quasiquote001/expected-                       test/quasiquote002/run-                       test/quasiquote002/*.idr-                       test/quasiquote002/expected-                       test/quasiquote003/run-                       test/quasiquote003/*.idr-                       test/quasiquote003/expected-                       test/quasiquote004/run-                       test/quasiquote004/*.idr-                       test/quasiquote004/expected-                       test/quasiquote005/run-                       test/quasiquote005/*.idr-                       test/quasiquote005/expected-                       test/quasiquote006/run-                       test/quasiquote006/*.idr-                       test/quasiquote006/expected--                       test/records001/run-                       test/records001/*.idr-                       test/records001/expected-                       test/records002/run-                       test/records002/*.idr-                       test/records002/expected-                       test/records003/run-                       test/records003/*.idr-                       test/records003/expected-                       test/records004/run-                       test/records004/*.idr-                       test/records004/expected-                       test/records005/run-                       test/records005/*.idr-                       test/records005/expected--                       test/sourceLocation001/run-                       test/sourceLocation001/*.idr-                       test/sourceLocation001/expected--                       test/sugar001/run-                       test/sugar001/*.idr-                       test/sugar001/expected-                       test/sugar002/run-                       test/sugar002/*.idr-                       test/sugar002/expected-                       test/sugar003/run-                       test/sugar003/*.idr-                       test/sugar003/expected-                       test/sugar004/run-                       test/sugar004/*.idr-                       test/sugar004/expected-                       test/sugar005/run-                       test/sugar005/*.idr-                       test/sugar005/expected--                       test/syntax001/run-                       test/syntax001/*.idr-                       test/syntax001/expected-                       test/syntax002/run-                       test/syntax002/*.idr-                       test/syntax002/expected--                       test/tactics001/run-                       test/tactics001/*.idr-                       test/tactics001/expected--                       test/totality001/run-                       test/totality001/*.idr-                       test/totality001/expected-                       test/totality002/run-                       test/totality002/*.idr-                       test/totality002/expected-                       test/totality003/run-                       test/totality003/*.idr-                       test/totality003/expected-                       test/totality004/run-                       test/totality004/*.idr-                       test/totality004/expected-                       test/totality005/run-                       test/totality005/*.idr-                       test/totality005/expected-                       test/totality006/run-                       test/totality006/*.idr-                       test/totality006/expected-                       test/totality007/run-                       test/totality007/*.ipkg-                       test/totality007/src/*.idr-                       test/totality007/expected-                       test/totality008/run-                       test/totality008/*.idr-                       test/totality008/expected-                       test/totality009/run-                       test/totality009/*.idr-                       test/totality009/expected-                       test/totality010/run-                       test/totality010/*.idr-                       test/totality010/expected-                       test/totality011/run-                       test/totality011/*.lidr-                       test/totality011/expected-                       test/totality012/run-                       test/totality012/*.idr-                       test/totality012/expected-                       test/totality013/run-                       test/totality013/*.idr-                       test/totality013/expected-                       test/totality014/run-                       test/totality014/*.idr-                       test/totality014/expected-                       test/totality015/run-                       test/totality015/*.idr-                       test/totality015/expected--                       test/tutorial001/run-                       test/tutorial001/*.idr-                       test/tutorial001/expected-                       test/tutorial002/run-                       test/tutorial002/*.idr-                       test/tutorial002/expected-                       test/tutorial003/run-                       test/tutorial003/*.idr-                       test/tutorial003/expected-                       test/tutorial004/run-                       test/tutorial004/*.idr-                       test/tutorial004/expected-                       test/tutorial005/run-                       test/tutorial005/*.idr-                       test/tutorial005/expected-                       test/tutorial006/run-                       test/tutorial006/*.idr-                       test/tutorial006/expected-                       test/tutorial007/run-                       test/tutorial007/*.idr-                       test/tutorial007/*.c-                       test/tutorial007/expected--                       test/unique001/run-                       test/unique001/*.idr-                       test/unique001/expected-                       test/unique002/run-                       test/unique002/*.idr-                       test/unique002/expected-                       test/unique003/run-                       test/unique003/*.idr-                       test/unique003/expected--                       test/views001/run-                       test/views001/*.idr-                       test/views001/expected-                       test/views002/run-                       test/views002/*.idr-                       test/views002/expected-                       test/views003/run-                       test/views003/*.idr-                       test/views003/expected--                       test/universes001/run-                       test/universes001/*.idr-                       test/universes001/expected-                       test/universes002/run-                       test/universes002/*.idr-                       test/universes002/expected--                       test/docs001/run-                       test/docs001/input-                       test/docs001/*.idr-                       test/docs001/expected-                       test/docs002/run-                       test/docs002/input-                       test/docs002/*.idr-                       test/docs002/expected-                       test/docs003/run-                       test/docs003/input-                       test/docs003/*.idr-                       test/docs003/expected-                       test/docs004/run-                       test/docs004/input-                       test/docs004/*.idr-                       test/docs004/expected-                       test/docs005/run-                       test/docs005/input-                       test/docs005/*.idr-                       test/docs005/expected---                       benchmarks/ALL-                       benchmarks/*.pl-                       benchmarks/README--                       benchmarks/fasta/fasta.idr-                       benchmarks/fasta/fasta.ipkg--                       benchmarks/pidigits/pidigits.idr-                       benchmarks/pidigits/pidigits.ipkg--                       benchmarks/quasigroups/board-                       benchmarks/quasigroups/*.idr-                       benchmarks/quasigroups/qgsolve.ipkg--                       benchmarks/trivial/sortvec.idr-                       benchmarks/trivial/sortvec.ipkg--                       icons/idris_icon.rc-                       icons/idris.ico- source-repository head   type:     git   location: git://github.com/idris-lang/Idris-dev.git@@ -989,8 +151,8 @@                 , Idris.Elab.Clause                 , Idris.Elab.Data                 , Idris.Elab.Record-                , Idris.Elab.Class-                , Idris.Elab.Instance+                , Idris.Elab.Interface+                , Idris.Elab.Implementation                 , Idris.Elab.Provider                 , Idris.Elab.RunElab                 , Idris.Elab.Transform@@ -1026,9 +188,13 @@                 , Idris.IdeMode                 , Idris.IdrisDoc                 , Idris.Imports+                , Idris.Info+                , Idris.Info.Show                 , Idris.Inliner                 , Idris.Interactive                 , Idris.Output+                , Idris.Main+                , Idris.ModeCommon                 , Idris.Parser                 , Idris.Parser.Helpers                 , Idris.Parser.Ops@@ -1042,6 +208,7 @@                 , Idris.Reflection                 , Idris.REPL                 , Idris.REPL.Parser+                , Idris.REPL.Commands                 , Idris.Transforms                 , Idris.TypeSearch                 , Idris.Unlit
jsrts/Runtime-node.js view
@@ -1,7 +1,7 @@ var i$putStr = (function() {   var fs = require('fs');   return function(s) {-    fs.write(1,s);+    fs.writeSync(1,s);   }; })(); 
libs/base/Control/Arrow.idr view
@@ -34,20 +34,20 @@   (Mor f) &&& (Mor g) = Mor $ \a => (f a, g a)  implementation Monad m => Arrow (Kleislimorphism m) where-  arrow f = Kleisli (return . f)+  arrow f = Kleisli (pure . f)   first (Kleisli f) =  Kleisli $ \(a, b) => do x <- f a-                                               return (x, b)+                                               pure (x, b)    second (Kleisli f) = Kleisli $ \(a, b) => do x <- f b-                                               return (a, x)+                                               pure (a, x)    (Kleisli f) *** (Kleisli g) = Kleisli $ \(a, b) => do x <- f a                                                         y <- g b-                                                        return (x, y)+                                                        pure (x, y)    (Kleisli f) &&& (Kleisli g) = Kleisli $ \a => do x <- f a                                                    y <- g a-                                                   return (x, y)+                                                   pure (x, y)  interface Arrow arr => ArrowZero (arr : Type -> Type -> Type) where   zeroArrow : arr a b
libs/base/Control/Catchable.idr view
@@ -24,7 +24,7 @@     catch (IOM prog) h = IOM (do p' <- prog                                  case p' of                                       Left e => let IOM he = h e in he-                                      Right val => return (Right val))+                                      Right val => pure (Right val))     throw = ioe_fail  implementation Catchable List () where
libs/base/Control/Category.idr view
@@ -15,7 +15,7 @@   (Mor f) . (Mor g) = with Basics (Mor (f . g))  implementation Monad m => Category (Kleislimorphism m) where-  id                        = Kleisli (return . id)+  id                        = Kleisli (pure . id)   (Kleisli f) . (Kleisli g) = Kleisli $ \a => g a >>= f  infixr 1 >>>
libs/base/Control/Monad/RWS.idr view
@@ -17,34 +17,34 @@    implementation Monad m => Functor (RWST r w s m) where     map f (MkRWST m) = MkRWST $ \r,s => do  (a, s', w) <- m r s-                                            return (f a, s', w)+                                            pure (f a, s', w)  implementation (Monoid w, Monad m) => Applicative (RWST r w s m) where-    pure a = MkRWST $ \_,s => return (a, s, neutral)+    pure a = MkRWST $ \_,s => pure (a, s, neutral)     (MkRWST f) <*> (MkRWST v) = MkRWST $ \r,s => do (a, s', w)   <- v r s                                                     (fn, ss, w') <- f r s-                                                    return (fn a, ss, w <+> w')+                                                    pure (fn a, ss, w <+> w')  implementation (Monoid w, Monad m) => Monad (RWST r w s m) where     (MkRWST m) >>= k = MkRWST $ \r,s => do  (a, s', w) <- m r s                                             let MkRWST ka = k a                                             (b, ss, w') <- ka r s'-                                            return (b, ss, w <+> w')+                                            pure (b, ss, w <+> w')  implementation (Monoid w, Monad m) => MonadReader r (RWST r w s m) where-    ask                = MkRWST $ \r,s => return (r, s, neutral)+    ask                = MkRWST $ \r,s => pure (r, s, neutral)     local f (MkRWST m) = MkRWST $ \r,s => m (f r) s  implementation (Monoid w, Monad m) => MonadWriter w (RWST r w s m) where-    tell w            = MkRWST $ \_,s => return ((), s, w)+    tell w            = MkRWST $ \_,s => pure ((), s, w)     listen (MkRWST m) = MkRWST $ \r,s => do (a, s', w) <- m r s-                                            return ((a, w), s', w)+                                            pure ((a, w), s', w)     pass (MkRWST m)   = MkRWST $ \r,s => do ((a, f), s', w) <- m r s-                                            return (a, s', f w)+                                            pure (a, s', f w)  implementation (Monoid w, Monad m) => MonadState s (RWST r w s m) where-    get   = MkRWST $ \_,s => return (s,  s, neutral)-    put s = MkRWST $ \_,_ => return ((), s, neutral)+    get   = MkRWST $ \_,s => pure (s,  s, neutral)+    put s = MkRWST $ \_,_ => pure ((), s, neutral)  implementation (Monoid w, Monad m) => MonadRWS r w s (RWST r w s m) where {} 
libs/base/Control/Monad/Reader.idr view
@@ -39,7 +39,7 @@                                  ka r  implementation Monad m => MonadReader r (ReaderT r m) where-    ask            = RD return+    ask            = RD pure     local f (RD m) = RD $ m . f  implementation MonadTrans (ReaderT r) where@@ -48,7 +48,7 @@ ||| Evaluate a function in the context of a Reader monad asks : MonadReader r m => (r -> a) -> m a asks f = do r <- ask-            return (f r)+            pure (f r)  ||| The reader monad. See MonadReader Reader : Type -> Type -> Type
libs/base/Control/Monad/State.idr view
@@ -27,7 +27,7 @@      (ST f) <*> (ST a) = ST (\st => do (g, r) <- f st                                       (b, t) <- a r-                                      return (g b, t))+                                      pure (g b, t))  implementation Monad m => Monad (StateT stateType m) where     (ST f) >>= k = ST (\st => do (v, st') <- f st@@ -35,12 +35,12 @@                                  kv st')  implementation Monad m => MonadState stateType (StateT stateType m) where-    get   = ST (\x => return (x, x))-    put x = ST (\y => return ((), x))+    get   = ST (\x => pure (x, x))+    put x = ST (\y => pure ((), x))  implementation MonadTrans (StateT stateType) where     lift x = ST (\st => do r <- x-                           return (r, st))+                           pure (r, st))  ||| Apply a function to modify the context of this computation modify : MonadState stateType m => (stateType -> stateType) -> m ()@@ -50,7 +50,7 @@ ||| Evaluate a function in the context held by this computation gets : MonadState stateType m => (stateType -> a) -> m a gets f = do s <- get-            return (f s)+            pure (f s)  ||| The State monad. See the MonadState interface State : (stateType : Type) -> (ty : Type) -> Type
libs/base/Control/Monad/Writer.idr view
@@ -36,30 +36,30 @@     (WR m) >>= k = WR $ do (a, w) <- m                            let WR ka = k a                            (b, w') <- ka-                           return (b, w <+> w')+                           pure (b, w <+> w')  implementation (Monoid w, Monad m) => MonadWriter w (WriterT w m) where-    tell w        = WR $ return ((), w)+    tell w        = WR $ pure ((), w)     listen (WR m) = WR $ do (a, w) <- m-                            return ((a, w), w)+                            pure ((a, w), w)     pass (WR m)   = WR $ do ((a, f), w) <- m-                            return (a, f w)+                            pure (a, f w)  implementation Monoid w => MonadTrans (WriterT w) where     lift x = WR $ do r <- x-                     return (r, neutral)+                     pure (r, neutral)  ||| Run an action in the Writer monad and transform the written output listens : MonadWriter w m => (w -> b) -> m a -> m (a, b) listens {m} f act = listens' f (listen act) where   listens' : (w -> b) -> m (a, w) -> m (a, b)   listens' f' ma = do (a, w) <- ma-                      return (a, f' w)+                      pure (a, f' w)  ||| Run an action, apply a function to it's output, and return it's value censor : MonadWriter w m => (w -> w) -> m a -> m a censor f m = pass $ do a <- m-                       return (a, f)+                       pure (a, f)  ||| The Writer monad itself. See the MonadWriter interface Writer : Type -> Type -> Type
libs/base/Data/Complex.idr view
@@ -27,7 +27,7 @@             plus_i = User 6  --- when we have a type class 'Fractional' (which contains Double),+-- when we have an interface 'Fractional' (which contains Double), -- we can do: {- implementation Fractional a => Fractional (Complex a) where
libs/base/Data/List.idr view
@@ -42,7 +42,7 @@ ||| @xs The list to be removed from ||| @p A proof that the element to be removed is in the list dropElem : (xs : List a) -> (p : Elem x xs) -> List a-dropElem (x :: ys) Here = ys +dropElem (x :: ys) Here = ys dropElem (x :: ys) (There p) = x :: dropElem ys p  ||| The intersectBy function returns the intersect of two lists by user-supplied equality predicate.
libs/base/Data/SortedSet.idr view
@@ -24,5 +24,5 @@ toList : SortedSet k -> List k toList (SetWrapper m) = map (\(i, _) => i) (Data.SortedMap.toList m) -instance Foldable SortedSet where+implementation Foldable SortedSet where   foldr f e xs = foldr f e (Data.SortedSet.toList xs)
libs/base/Data/String.idr view
@@ -86,11 +86,11 @@                      do                        w <- cast <$> parseInteger whole                        e <- parseInteger exp-                       return (w, 0, e)+                       pure (w, 0, e)                    (whole::[]) =>                            do                        w <- cast <$> parseInteger whole-                       return (w, 0, 0)+                       pure (w, 0, 0)                    _ => Nothing                (whole::fracAndExp::[]) =>                  case split (\c => c == 'e' || c == 'E') fracAndExp of@@ -101,12 +101,12 @@                        f <- (/ (pow 10 (length frac))) <$>                              (cast <$> parseNumWithoutSign (unpack frac) 0)                        e <- parseInteger exp-                       return (w, if w < 0 then (-f) else f, e)+                       pure (w, if w < 0 then (-f) else f, e)                    (frac::[]) =>                            do                        w <- cast <$> parseInteger whole                        f <- (/ (pow 10 (length frac))) <$>                              (cast <$> parseNumWithoutSign (unpack frac) 0)-                       return (w, if w < 0 then (-f) else f, 0)+                       pure (w, if w < 0 then (-f) else f, 0)                    _ => Nothing                _ => Nothing
libs/base/Debug/Trace.idr view
@@ -5,6 +5,6 @@ ||| @ result the final result export trace : (msg : String) -> (result : a) -> a-trace x val = unsafePerformIO {ffi=FFI_C} (do putStrLn x; return val)+trace x val = unsafePerformIO {ffi=FFI_C} (do putStrLn x; pure val)  
libs/base/Language/Reflection/Utils.idr view
@@ -87,12 +87,12 @@     showPrec d (WhereN i n1 n2) = showCon d "WhereN" $ showArg i ++                             showArg n1 ++ showArg n2     showPrec d (WithN i n) = showCon d "WithN" $ showArg i ++ showArg n-    showPrec d (InstanceN i ss) = showCon d "InstanceN" $ showArg i ++ showArg ss+    showPrec d (ImplementationN i ss) = showCon d "ImplementationN" $ showArg i ++ showArg ss     showPrec d (ParentN n s) = showCon d "ParentN" $ showArg n ++ showArg s     showPrec d (MethodN n) = showCon d "MethodN" $ showArg n     showPrec d (CaseN fc n) = showCon d "CaseN" $ showArg fc ++ showArg n     showPrec d (ElimN n) = showCon d "ElimN" $ showArg n-    showPrec d (InstanceCtorN n) = showCon d "InstanceCtorN" $ showArg n+    showPrec d (ImplementationCtorN n) = showCon d "ImplementationCtorN" $ showArg n     showPrec d (MetaN parent meta) = showCon d "MetaN" $ showArg parent ++ showArg meta    implementation Show TTName where@@ -110,16 +110,16 @@     x          == y             = False    implementation Eq SpecialName where-    (WhereN i n1 n2)    == (WhereN i' n1' n2')   = i == i' && n1 == n1' && n2 == n2'-    (WithN i n)         == (WithN i' n')         = i == i' && n == n'-    (InstanceN i ss)    == (InstanceN i' ss')    = i == i' && ss == ss'-    (ParentN n s)       == (ParentN n' s')       = n == n' && s == s'-    (MethodN n)         == (MethodN n')          = n == n'-    (CaseN fc n)        == (CaseN fc' n')        = fc == fc' && n == n'-    (ElimN n)           == (ElimN n')            = n == n'-    (InstanceCtorN n)   == (InstanceCtorN n')    = n == n'-    (MetaN parent meta) == (MetaN parent' meta') = parent == parent' && meta == meta'-    _                   == _                     = False+    (WhereN i n1 n2)        == (WhereN i' n1' n2')      = i == i' && n1 == n1' && n2 == n2'+    (WithN i n)             == (WithN i' n')            = i == i' && n == n'+    (ImplementationN i ss)  == (ImplementationN i' ss') = i == i' && ss == ss'+    (ParentN n s)           == (ParentN n' s')          = n == n' && s == s'+    (MethodN n)             == (MethodN n')             = n == n'+    (CaseN fc n)            == (CaseN fc' n')           = fc == fc' && n == n'+    (ElimN n)               == (ElimN n')               = n == n'+    (ImplementationCtorN n) == (ImplementationCtorN n') = n == n'+    (MetaN parent meta)     == (MetaN parent' meta')    = parent == parent' && meta == meta'+    _                       == _                        = False  implementation Show TTUExp where   showPrec d (UVar ns i) = showCon d "UVar" $ showArg ns ++ showArg i@@ -347,7 +347,7 @@ pure = id  ----------------------------------------- Instances for definition reflection+-- Implementations for definition reflection -------------------------------------- implementation Show Erasure where   show Erased    = "Erased"
libs/base/System.idr view
@@ -22,14 +22,14 @@ setEnv : String -> String -> IO Bool setEnv key value = do   ok <- foreign FFI_C "setenv" (String -> String -> Int -> IO Int) key value 1-  return (ok == 0)+  pure (ok == 0)  ||| Unsets an environment variable. ||| Returns true if the variable was able to be unset. unsetEnv : String -> IO Bool unsetEnv key = do   ok <- foreign FFI_C "unsetenv" (String -> IO Int) key-  return (ok == 0)+  pure (ok == 0)  getEnvironment : IO (List (String, String)) getEnvironment = getAllPairs 0 []@@ -49,7 +49,7 @@       envPair <- getEnvPair n       is_nil  <- nullStr envPair       if is_nil-         then return $ reverse $ map splitEq acc+         then pure $ reverse $ map splitEq acc          else getAllPairs (n + 1) (envPair :: acc)  ||| Quit with a particular exit code@@ -59,7 +59,7 @@ ||| Get the numbers of seconds since 1st January 1970, 00:00 UTC  time : IO Integer time = do MkRaw t <- foreign FFI_C "idris_time" (IO (Raw Integer))-          return t+          pure t  usleep : Int -> IO () usleep i = foreign FFI_C "usleep" (Int -> IO ()) i
+ libs/base/System/Concurrency/Channels.idr view
@@ -0,0 +1,63 @@+module System.Concurrency.Channels++import System.Concurrency.Raw++||| A Channel is a connection between two processes. Channels can be created+||| either using 'listen' to wait for an incoming connection, or 'connect'+||| which initiates a connection to another process.+||| Channels cannot (yet) be passed between processes.+export+data Channel : Type where+     MkConc : (pid : Ptr) -> (ch_id : Int) -> Channel++||| A PID is a process identifier, as returned by `spawn`+export+data PID : Type where+     MkPID : (pid : Ptr) -> PID++||| Spawn a process in a new thread, returning the process ID+export+spawn : (process : IO ()) -> IO PID+spawn proc = do pid <- fork proc+                pure (MkPID pid)++||| Create a channel which connects this process to another process+export+connect : (pid : PID) -> IO (Maybe Channel)+connect (MkPID pid) = do ch_id <- sendToThread pid 0 ()+                         if (ch_id /= 0)+                            then pure (Just (MkConc pid ch_id))+                            else pure Nothing++||| Listen for incoming connections. If another process has initiated a+||| communication with this process, returns a channel +export+listen : (timeout : Int) -> IO (Maybe Channel)+listen timeout = do checkMsgsTimeout timeout+                    Just (client, ch_id) <- listenMsgs+                       | Nothing => pure Nothing+                    getMsgFrom {a = ()} client ch_id -- remove init message+                    pure (Just (MkConc client ch_id))++||| Send a message on a channel. Returns whether the message was successfully+||| sent to the process at the other end of the channel. This will fail if+||| the process on the channel is no longer running.+||| This is unsafe because there is no type checking, so there must be+||| a protocol (externally checked) which ensures that the message send+||| is of type expected by the receiver.+export+unsafeSend : Channel -> (val : a) -> IO Bool+unsafeSend (MkConc pid ch_id) val+     = do ok <- sendToThread pid ch_id val+          pure (ok /= 0)++||| Receive a message on a channel, with an explicit type.+||| Blocks if there is nothing to receive. Returns `Nothing` if the+||| process on the channel is no longer running.+||| This is unsafe because there is no type checking, so there must be+||| a protocol (externally checked) which ensures that the message received+||| is of the type given by the sender.+export+unsafeRecv : (expected : Type) -> Channel -> IO (Maybe expected)+unsafeRecv a (MkConc pid ch_id) = getMsgFrom {a} pid ch_id+
libs/base/System/Concurrency/Raw.idr view
@@ -1,5 +1,3 @@--- WARNING: No guarantees that this works properly yet!- module System.Concurrency.Raw  -- Raw (i.e. not type safe) message passing@@ -15,24 +13,26 @@ |||          the receiver will create a new channel ID sendToThread : (thread_id : Ptr) -> (channel : Int) -> a -> IO Int sendToThread {a} dest channel val-   = foreign FFI_C "idris_sendMessage" (Ptr -> Int -> Ptr -> Raw a -> IO Int)-                prim__vm channel dest (MkRaw val)+   = do me <- getMyVM+        foreign FFI_C "idris_sendMessage" (Ptr -> Int -> Ptr -> Raw a -> IO Int)+                me channel dest (MkRaw val)  ||| Check for messages in the process inbox checkMsgs : IO Bool-checkMsgs = do msgs <- foreign FFI_C "idris_checkMessages" (Ptr -> IO Ptr)-                            prim__vm+checkMsgs = do me <- getMyVM+               msgs <- foreign FFI_C "idris_checkMessages" (Ptr -> IO Ptr) me                null <- nullPtr msgs-               return (not null)+               pure (not null)  ||| Check for messages in the process inbox ||| If no messages, waits for the given number of seconds checkMsgsTimeout : Int -> IO Bool checkMsgsTimeout timeout-          = do msgs <- foreign FFI_C "idris_checkMessagesTimeout" -                            (Ptr -> Int -> IO Ptr) prim__vm timeout+          = do me <- getMyVM+               msgs <- foreign FFI_C "idris_checkMessagesTimeout" +                            (Ptr -> Int -> IO Ptr) me timeout                null <- nullPtr msgs-               return (not null)+               pure (not null)  private sender : Ptr -> IO Ptr@@ -46,8 +46,9 @@ ||| Returns either 'Nothing', if none, or 'Just (pid, channel)' as pid  ||| of sender and new channel id. listenMsgs : IO (Maybe (Ptr, Int))-listenMsgs = do msg <- foreign FFI_C "idris_checkInitMessages" (Ptr -> IO Ptr)-                             prim__vm+listenMsgs = do me <- getMyVM+                msg <- foreign FFI_C "idris_checkInitMessages" (Ptr -> IO Ptr)+                             me                 null <- nullPtr msg                 if null then pure Nothing                         else do s_id <- sender msg@@ -58,20 +59,21 @@ ||| If channel is '0', accept on any channel. checkMsgsFrom : Ptr -> (channel : Int) -> IO Bool checkMsgsFrom sender channel -  = do msgs <- foreign FFI_C "idris_checkMessagesFrom" (Ptr -> Int -> Ptr -> IO Ptr)-                             prim__vm channel sender+  = do me <- getMyVM+       msgs <- foreign FFI_C "idris_checkMessagesFrom" (Ptr -> Int -> Ptr -> IO Ptr)+                             me channel sender        null <- nullPtr msgs-       return (not null)+       pure (not null)  ||| Check inbox for messages. If there are none, blocks until a message ||| arrives. ||| Note that this is not at all type safe! It is intended to be used in ||| a type safe wrapper. getMsg : IO a-getMsg {a} = do m <- foreign FFI_C "idris_recvMessage" -                             (Ptr -> IO Ptr) prim__vm+getMsg {a} = do me <- getMyVM+                m <- foreign FFI_C "idris_recvMessage" (Ptr -> IO Ptr) me                 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m-                return x+                pure x  ||| Check inbox for messages. If there are none, blocks until a message ||| arrives. Return triple of sender's ID, channel ID, and the message.@@ -79,21 +81,23 @@ ||| a type safe wrapper. getMsgWithSender : IO (Ptr, Int, a) getMsgWithSender {a} -           = do m <- foreign FFI_C "idris_recvMessage" -                             (Ptr -> IO Ptr) prim__vm+           = do me <- getMyVM+                m <- foreign FFI_C "idris_recvMessage" +                             (Ptr -> IO Ptr) me                 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m                 vm <- sender m                 chan <- channel_id m                 foreign FFI_C "idris_freeMsg" (Ptr -> IO ()) m-                return (vm, chan, x)+                pure (vm, chan, x)  ||| Check inbox for messages on a particular channel. If there are none, ||| blocks until a message arrives. Returns `Nothing` if the sender isn't ||| alive getMsgFrom : Ptr -> (channel : Int) -> IO (Maybe a) getMsgFrom {a} sender channel -  = do m <- foreign FFI_C "idris_recvMessageFrom"-                    (Ptr -> Int -> Ptr -> IO Ptr) prim__vm channel sender+  = do me <- getMyVM+       m <- foreign FFI_C "idris_recvMessageFrom"+                    (Ptr -> Int -> Ptr -> IO Ptr) me channel sender        null <- nullPtr m        if null            then pure Nothing
− libs/base/System/Concurrency/Sessions.idr
@@ -1,63 +0,0 @@-module System.Concurrency.Sessions--import System.Concurrency.Raw--||| A Session is a connection between two processes. Sessions can be created-||| either using 'listen' to wait for an incoming connection, or 'connect'-||| which initiates a connection to another process.-||| Sessions cannot be passed between processes.-export-data Session : Type where-     MkConc : (pid : Ptr) -> (ch_id : Int) -> Session--||| A PID is a process identifier, as returned by `spawn`-export-data PID : Type where-     MkPID : (pid : Ptr) -> PID--||| Spawn a process in a new thread, returning the process ID-export-spawn : IO () -> IO PID-spawn proc = do pid <- fork proc-                pure (MkPID pid)--||| Create a channel which connects this process to another process-export-connect : (proc : PID) -> IO (Maybe Session)-connect (MkPID pid) = do ch_id <- sendToThread pid 0 ()-                         if (ch_id /= 0)-                            then pure (Just (MkConc pid ch_id))-                            else pure Nothing--||| Listen for incoming connections. If another process has initiated a-||| communication with this process, returns a channel -export-listen : (timeout : Int) -> IO (Maybe Session)-listen timeout = do checkMsgsTimeout timeout-                    Just (client, ch_id) <- listenMsgs-                       | Nothing => pure Nothing-                    getMsgFrom {a = ()} client ch_id -- remove init message-                    pure (Just (MkConc client ch_id))--||| Send a message on a channel. Returns whether the message was successfully-||| sent to the process at the other end of the channel. This will fail if-||| the process on the channel is no longer running.-||| This is unsafe because there is no type checking, so there must be-||| a protocol (externally checked) which ensures that the message send-||| is of type expected by the receiver.-export-unsafeSend : Session -> (val : a) -> IO Bool-unsafeSend (MkConc pid ch_id) val-     = do ok <- sendToThread pid ch_id val-          pure (ok /= 0)--||| Receive a message on a channel, with an explicit type.-||| Blocks if there is nothing to receive. Returns `Nothing` if the-||| process on the channel is no longer running.-||| This is unsafe because there is no type checking, so there must be-||| a protocol (externally checked) which ensures that the message received-||| is of the type given by the sender.-export-unsafeRecv : (a : Type) -> Session -> IO (Maybe a)-unsafeRecv a (MkConc pid ch_id) = getMsgFrom {a} pid ch_id-
libs/base/base.ipkg view
@@ -31,5 +31,5 @@           Control.Category, Control.Arrow,           Control.Catchable, Control.IOExcept, -          System.Concurrency.Raw, System.Concurrency.Sessions+          System.Concurrency.Raw, System.Concurrency.Channels 
libs/contrib/CFFI/Memory.idr view
@@ -33,7 +33,7 @@  ||| Allocate enough memory to hold an instance of a C typr alloc : Composite -> IO CPtr-alloc t = return $ CPt !(calloc 1 (sizeOf t)) 0+alloc t = pure $ CPt !(calloc 1 (sizeOf t)) 0  ||| Free memory allocated with alloc free : CPtr -> IO ()@@ -63,24 +63,24 @@ ||| Write to memory poke : (t : CType) -> CPtr -> translate t -> IO () poke I8 (CPt p o) x = do _ <- prim_poke8 p o x-                         return ()+                         pure () poke I16 (CPt p o) x = do _ <- prim_poke16 p o x-                          return ()+                          pure () poke I32 (CPt p o) x = do _ <- prim_poke32 p o x-                          return ()+                          pure () poke I64 (CPt p o) x = do _ <- prim_poke64 p o x-                          return ()+                          pure () poke PTR (CPt p o) x = do _ <- prim_pokePtr p o x-                          return ()+                          pure () poke FLOAT (CPt p o) x = do _ <- prim_pokeSingle p o x-                            return ()+                            pure () poke DOUBLE (CPt p o) x = do _ <- prim_pokeDouble p o x-                             return ()+                             pure ()  ||| Update memory with a function. update : (t: CType) -> CPtr -> (translate t -> translate t) -> IO () update ty cp f = do val <- peek ty cp-                    out <- return $ f val+                    out <- pure $ f val                     poke ty cp out  ||| Get a pointer to a field in a composite value
− libs/contrib/Classes/Verified.idr
@@ -1,123 +0,0 @@-module Classes.Verified--import Control.Algebra-import Control.Algebra.Lattice-import Control.Algebra.VectorSpace--%access public export---- Due to these being basically unused and difficult to implement,--- they're in contrib for a bit. Once a design is found that lets them--- be implemented for a number of implementations, and we get those--- implementations, then some of them can move back to base (or even--- prelude, in the cases of Functor, Applicative, Monad, Semigroup,--- and Monoid).--interface Functor f => VerifiedFunctor (f : Type -> Type) where-  functorIdentity : {a : Type} -> (x : f a) -> map Basics.id x = Basics.id x-  functorComposition : {a : Type} -> {b : Type} -> (x : f a) ->-                       (g1 : a -> b) -> (g2 : b -> c) ->-                       map (g2 . g1) x = (map g2 . map g1) x--interface (Applicative f, VerifiedFunctor f) => VerifiedApplicative (f : Type -> Type) where-  applicativeMap : (x : f a) -> (g : a -> b) ->-                   map g x = pure g <*> x-  applicativeIdentity : (x : f a) -> pure Basics.id <*> x = x-  applicativeComposition : (x : f a) -> (g1 : f (a -> b)) -> (g2 : f (b -> c)) ->-                           ((pure (.) <*> g2) <*> g1) <*> x = g2 <*> (g1 <*> x)-  applicativeHomomorphism : (x : a) -> (g : a -> b) ->-                            (<*>) {f} (pure g) (pure x) = pure {f} (g x)-  applicativeInterchange : (x : a) -> (g : f (a -> b)) ->-                           g <*> pure x = pure (\g' : (a -> b) => g' x) <*> g--interface (Monad m, VerifiedApplicative m) => VerifiedMonad (m : Type -> Type) where-  monadApplicative : (mf : m (a -> b)) -> (mx : m a) ->-                     mf <*> mx = mf >>= \f =>-                                 mx >>= \x =>-                                        pure (f x)-  monadLeftIdentity : (x : a) -> (f : a -> m b) -> return x >>= f = f x-  monadRightIdentity : (mx : m a) -> mx >>= Monad.return = mx-  monadAssociativity : (mx : m a) -> (f : a -> m b) -> (g : b -> m c) ->-                       (mx >>= f) >>= g = mx >>= (\x => f x >>= g)---interface Semigroup a => VerifiedSemigroup a where-  total semigroupOpIsAssociative : (l, c, r : a) -> l <+> (c <+> r) = (l <+> c) <+> r--implementation VerifiedSemigroup (List a) where-  semigroupOpIsAssociative = appendAssociative----implementation VerifiedSemigroup Nat where---  semigroupOpIsAssociative = plusAssociative---interface (VerifiedSemigroup a, Monoid a) => VerifiedMonoid a where-  total monoidNeutralIsNeutralL : (l : a) -> l <+> Algebra.neutral = l-  total monoidNeutralIsNeutralR : (r : a) -> Algebra.neutral <+> r = r---- implementation VerifiedMonoid Nat where---   monoidNeutralIsNeutralL = plusZeroRightNeutral---   monoidNeutralIsNeutralR = plusZeroLeftNeutral--implementation VerifiedMonoid (List a) where-  monoidNeutralIsNeutralL = appendNilRightNeutral-  monoidNeutralIsNeutralR xs = Refl--interface (VerifiedMonoid a, Group a) => VerifiedGroup a where-  total groupInverseIsInverseL : (l : a) -> l <+> inverse l = Algebra.neutral-  total groupInverseIsInverseR : (r : a) -> inverse r <+> r = Algebra.neutral--interface (VerifiedGroup a, AbelianGroup a) => VerifiedAbelianGroup a where-  total abelianGroupOpIsCommutative : (l, r : a) -> l <+> r = r <+> l--interface (VerifiedAbelianGroup a, Ring a) => VerifiedRing a where-  total ringOpIsAssociative   : (l, c, r : a) -> l <.> (c <.> r) = (l <.> c) <.> r-  total ringOpIsDistributiveL : (l, c, r : a) -> l <.> (c <+> r) = (l <.> c) <+> (l <.> r)-  total ringOpIsDistributiveR : (l, c, r : a) -> (l <+> c) <.> r = (l <.> r) <+> (c <.> r)--interface (VerifiedRing a, RingWithUnity a) => VerifiedRingWithUnity a where-  total ringWithUnityIsUnityL : (l : a) -> l <.> Algebra.unity = l-  total ringWithUnityIsUnityR : (r : a) -> Algebra.unity <.> r = r----interface (VerifiedRingWithUnity a, Field a) => VerifiedField a where---  total fieldInverseIsInverseL : (l : a) -> (notId : Not (l = neutral)) -> l <.> (inverseM l notId) = Algebra.unity---  total fieldInverseIsInverseR : (r : a) -> (notId : Not (r = neutral)) -> (inverseM r notId) <.> r = Algebra.unity---interface JoinSemilattice a => VerifiedJoinSemilattice a where-  total joinSemilatticeJoinIsAssociative : (l, c, r : a) -> join l (join c r) = join (join l c) r-  total joinSemilatticeJoinIsCommutative : (l, r : a)    -> join l r = join r l-  total joinSemilatticeJoinIsIdempotent  : (e : a)       -> join e e = e--interface MeetSemilattice a => VerifiedMeetSemilattice a where-  total meetSemilatticeMeetIsAssociative : (l, c, r : a) -> meet l (meet c r) = meet (meet l c) r-  total meetSemilatticeMeetIsCommutative : (l, r : a)    -> meet l r = meet r l-  total meetSemilatticeMeetIsIdempotent  : (e : a)       -> meet e e = e--{- FIXME: Some maintenance required here.-   Algebra.top and Algebra.bottom don't exist!--}-{---interface (VerifiedJoinSemilattice a, BoundedJoinSemilattice a) => VerifiedBoundedJoinSemilattice a where-  total boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e Algebra.bottom = e--interface (VerifiedMeetSemilattice a, BoundedMeetSemilattice a) => VerifiedBoundedMeetSemilattice a where-  total boundedMeetSemilatticeTopIsTop : (e : a) -> meet e Algebra.top = e--interface (VerifiedJoinSemilattice a, VerifiedMeetSemilattice a) => VerifiedLattice a where-  total latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l-  total latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l--interface (VerifiedBoundedJoinSemilattice a, VerifiedBoundedMeetSemilattice a, VerifiedLattice a) => VerifiedBoundedLattice a where { }-----interface (VerifiedRingWithUnity a, VerifiedAbelianGroup b, Module a b) => VerifiedModule a b where---  total moduleScalarMultiplyComposition : (x,y : a) -> (v : b) -> x <#> (y <#> v) = (x <.> y) <#> v---  total moduleScalarUnityIsUnity : (v : b) -> Algebra.unity {a} <#> v = v---  total moduleScalarMultDistributiveWRTVectorAddition : (s : a) -> (v, w : b) -> s <#> (v <+> w) = (s <#> v) <+> (s <#> w)---  total moduleScalarMultDistributiveWRTModuleAddition : (s, t : a) -> (v : b) -> (s <+> t) <#> v = (s <#> v) <+> (t <#> v)----interface (VerifiedField a, VerifiedModule a b) => VerifiedVectorSpace a b where {}---}
+ libs/contrib/Control/Algebra/NumericImplementations.idr view
@@ -0,0 +1,114 @@+||| Implementations of algebraic interfaces (group, ring, etc) for numeric data types,+||| and Complex number types.+module Control.Algebra.NumericImplementations++import Control.Algebra+import Control.Algebra.VectorSpace+import Data.Complex+import Data.ZZ++%access public export++Semigroup Integer where+  (<+>) = (+)++Monoid Integer where+  neutral = 0++Group Integer where+  inverse = (* -1)++AbelianGroup Integer where ++Ring Integer where+  (<.>) = (*)++RingWithUnity Integer where+  unity = 1+++Semigroup Int where+  (<+>) = (+)++Monoid Int where+  neutral = 0++Group Int where+  inverse = (* -1)++AbelianGroup Int where++Ring Int where+  (<.>) = (*)++RingWithUnity Int where+  unity = 1+++Semigroup Double where+  (<+>) = (+)++Monoid Double where+  neutral = 0++Group Double where+  inverse = (* -1)++AbelianGroup Double where++Ring Double where+  (<.>) = (*)++RingWithUnity Double where+  unity = 1++Field Double where+  inverseM f _ = 1 / f+++Semigroup Nat where+  (<+>) = (+)++Monoid Nat where+  neutral = 0++Semigroup ZZ where+  (<+>) = (+)++Monoid ZZ where+  neutral = 0++Group ZZ where+  inverse = (* -1)++AbelianGroup ZZ where++Ring ZZ where+  (<.>) = (*)++RingWithUnity ZZ where+  unity = 1+++Semigroup a => Semigroup (Complex a) where+  (<+>) (a :+ b) (c :+ d) = (a <+> c) :+ (b <+> d)++Monoid a => Monoid (Complex a) where+  neutral = (neutral :+ neutral)++Group a => Group (Complex a) where+  inverse (r :+ i) = (inverse r :+ inverse i)++Ring a => AbelianGroup (Complex a) where {}++Ring a => Ring (Complex a) where+  (<.>) (a :+ b) (c :+ d) = (a <.> c <-> b <.> d) :+ (a <.> d <+> b <.> c)++RingWithUnity a => RingWithUnity (Complex a) where+  unity = (unity :+ neutral)++RingWithUnity a => Module a (Complex a) where+  (<#>) x = map (x <.>)++RingWithUnity a => InnerProductSpace a (Complex a) where+  (x :+ y) <||> z = realPart $ (x :+ inverse y) <.> z
− libs/contrib/Control/Algebra/NumericInstances.idr
@@ -1,114 +0,0 @@-||| Instances of algebraic classes (group, ring, etc) for numeric data types,-||| and Complex number types.-module Control.Algebra.NumericInstances--import Control.Algebra-import Control.Algebra.VectorSpace-import Data.Complex-import Data.ZZ--%access public export--Semigroup Integer where-  (<+>) = (+)--Monoid Integer where-  neutral = 0--Group Integer where-  inverse = (* -1)--AbelianGroup Integer where --Ring Integer where-  (<.>) = (*)--RingWithUnity Integer where-  unity = 1---Semigroup Int where-  (<+>) = (+)--Monoid Int where-  neutral = 0--Group Int where-  inverse = (* -1)--AbelianGroup Int where--Ring Int where-  (<.>) = (*)--RingWithUnity Int where-  unity = 1---Semigroup Double where-  (<+>) = (+)--Monoid Double where-  neutral = 0--Group Double where-  inverse = (* -1)--AbelianGroup Double where--Ring Double where-  (<.>) = (*)--RingWithUnity Double where-  unity = 1--Field Double where-  inverseM f _ = 1 / f---Semigroup Nat where-  (<+>) = (+)--Monoid Nat where-  neutral = 0--Semigroup ZZ where-  (<+>) = (+)--Monoid ZZ where-  neutral = 0--Group ZZ where-  inverse = (* -1)--AbelianGroup ZZ where--Ring ZZ where-  (<.>) = (*)--RingWithUnity ZZ where-  unity = 1---Semigroup a => Semigroup (Complex a) where-  (<+>) (a :+ b) (c :+ d) = (a <+> c) :+ (b <+> d)--Monoid a => Monoid (Complex a) where-  neutral = (neutral :+ neutral)--Group a => Group (Complex a) where-  inverse (r :+ i) = (inverse r :+ inverse i)--Ring a => AbelianGroup (Complex a) where {}--Ring a => Ring (Complex a) where-  (<.>) (a :+ b) (c :+ d) = (a <.> c <-> b <.> d) :+ (a <.> d <+> b <.> c)--RingWithUnity a => RingWithUnity (Complex a) where-  unity = (unity :+ neutral)--RingWithUnity a => Module a (Complex a) where-  (<#>) x = map (x <.>)--RingWithUnity a => InnerProductSpace a (Complex a) where-  (x :+ y) <||> z = realPart $ (x :+ inverse y) <.> z
libs/contrib/Data/Heap.idr view
@@ -173,5 +173,5 @@   _ <- printLn $ main.sort [10, 3, 7, 2, 9, 1, 8, 0, 6, 4, 5]   _ <- printLn $ main.sort ["orange", "apple", "pear", "lime", "durian"]   _ <- printLn $ main.sort [("jim", 19, "cs"), ("alice", 20, "english"), ("bob", 50, "engineering")]-  return ()+  pure () -}
libs/contrib/Data/Matrix/Algebraic.idr view
@@ -1,11 +1,11 @@ ||| Matrix operations with vector space dimensionalities enforced-||| at the type level. Uses operations from classes in `Control.Algebra`+||| at the type level. Uses operations from interfaces in `Control.Algebra` ||| and `Control.Algebra.VectorSpace`. module Data.Matrix.Algebraic  import public Control.Algebra import public Control.Algebra.VectorSpace-import public Control.Algebra.NumericInstances+import public Control.Algebra.NumericImplementations  import public Data.Matrix @@ -23,7 +23,7 @@ infixr 7 <&>  -- matrix tensor product  --------------------------------------------------------------------------               Vectors as members of algebraic classes+--               Vectors as members of algebraic interfaces -----------------------------------------------------------------------  implementation Semigroup a => Semigroup (Vect n a) where@@ -146,4 +146,4 @@ --                      Matrix Algebra Properties ----------------------------------------------------------------------- --- TODO: Prove properties of matrix algebra for 'Verified' algebraic classes+-- TODO: Prove properties of matrix algebra for 'Verified' algebraic interfaces
libs/contrib/Data/Matrix/Numeric.idr view
@@ -1,5 +1,5 @@ ||| Matrix operations with vector space dimensionalities enforced-||| at the type level. Uses operations from the Num type class.+||| at the type level. Uses operations from the Num interface. module Data.Matrix.Numeric  import public Data.Matrix
libs/contrib/Data/Storable.idr view
@@ -14,7 +14,7 @@     peek p offset = prim_peek8 p offset     poke p offset val = do         _ <- prim_poke8 p offset val-        return ()+        pure ()  Storable Bits16 where     sizeOf _ = 2@@ -22,7 +22,7 @@     peek p offset = prim_peek16 p offset     poke p offset val = do         _ <- prim_poke16 p offset val-        return ()+        pure ()  Storable Bits32 where     sizeOf _ = 4@@ -30,7 +30,7 @@     peek p offset = prim_peek32 p offset     poke p offset val = do         _ <- prim_poke32 p offset val-        return ()+        pure ()  Storable Bits64 where     sizeOf _ = 8@@ -38,4 +38,4 @@     peek p offset = prim_peek64 p offset     poke p offset val = do         _ <- prim_poke64 p offset val-        return ()+        pure ()
libs/contrib/Decidable/Decidable.idr view
@@ -9,7 +9,7 @@ -- Interface for decidable n-ary Relations -------------------------------------------------------------------------------- ---  Note: Instance resolution for Decidable is likely to not work in the REPL+--  Note: Implementation resolution for Decidable is likely to not work in the REPL --        at the moment. interface Decidable (ts : Vect k Type) (p : Rel ts) where   total decide : liftRel ts p Dec
+ libs/contrib/Interfaces/Verified.idr view
@@ -0,0 +1,123 @@+module Interfaces.Verified++import Control.Algebra+import Control.Algebra.Lattice+import Control.Algebra.VectorSpace++%access public export++-- Due to these being basically unused and difficult to implement,+-- they're in contrib for a bit. Once a design is found that lets them+-- be implemented for a number of implementations, and we get those+-- implementations, then some of them can move back to base (or even+-- prelude, in the cases of Functor, Applicative, Monad, Semigroup,+-- and Monoid).++interface Functor f => VerifiedFunctor (f : Type -> Type) where+  functorIdentity : {a : Type} -> (x : f a) -> map Basics.id x = Basics.id x+  functorComposition : {a : Type} -> {b : Type} -> (x : f a) ->+                       (g1 : a -> b) -> (g2 : b -> c) ->+                       map (g2 . g1) x = (map g2 . map g1) x++interface (Applicative f, VerifiedFunctor f) => VerifiedApplicative (f : Type -> Type) where+  applicativeMap : (x : f a) -> (g : a -> b) ->+                   map g x = pure g <*> x+  applicativeIdentity : (x : f a) -> pure Basics.id <*> x = x+  applicativeComposition : (x : f a) -> (g1 : f (a -> b)) -> (g2 : f (b -> c)) ->+                           ((pure (.) <*> g2) <*> g1) <*> x = g2 <*> (g1 <*> x)+  applicativeHomomorphism : (x : a) -> (g : a -> b) ->+                            (<*>) {f} (pure g) (pure x) = pure {f} (g x)+  applicativeInterchange : (x : a) -> (g : f (a -> b)) ->+                           g <*> pure x = pure (\g' : (a -> b) => g' x) <*> g++interface (Monad m, VerifiedApplicative m) => VerifiedMonad (m : Type -> Type) where+  monadApplicative : (mf : m (a -> b)) -> (mx : m a) ->+                     mf <*> mx = mf >>= \f =>+                                 mx >>= \x =>+                                        pure (f x)+  monadLeftIdentity : (x : a) -> (f : a -> m b) -> pure x >>= f = f x+  monadRightIdentity : (mx : m a) -> mx >>= pure = mx+  monadAssociativity : (mx : m a) -> (f : a -> m b) -> (g : b -> m c) ->+                       (mx >>= f) >>= g = mx >>= (\x => f x >>= g)+++interface Semigroup a => VerifiedSemigroup a where+  total semigroupOpIsAssociative : (l, c, r : a) -> l <+> (c <+> r) = (l <+> c) <+> r++implementation VerifiedSemigroup (List a) where+  semigroupOpIsAssociative = appendAssociative++--implementation VerifiedSemigroup Nat where+--  semigroupOpIsAssociative = plusAssociative+++interface (VerifiedSemigroup a, Monoid a) => VerifiedMonoid a where+  total monoidNeutralIsNeutralL : (l : a) -> l <+> Algebra.neutral = l+  total monoidNeutralIsNeutralR : (r : a) -> Algebra.neutral <+> r = r++-- implementation VerifiedMonoid Nat where+--   monoidNeutralIsNeutralL = plusZeroRightNeutral+--   monoidNeutralIsNeutralR = plusZeroLeftNeutral++implementation VerifiedMonoid (List a) where+  monoidNeutralIsNeutralL = appendNilRightNeutral+  monoidNeutralIsNeutralR xs = Refl++interface (VerifiedMonoid a, Group a) => VerifiedGroup a where+  total groupInverseIsInverseL : (l : a) -> l <+> inverse l = Algebra.neutral+  total groupInverseIsInverseR : (r : a) -> inverse r <+> r = Algebra.neutral++interface (VerifiedGroup a, AbelianGroup a) => VerifiedAbelianGroup a where+  total abelianGroupOpIsCommutative : (l, r : a) -> l <+> r = r <+> l++interface (VerifiedAbelianGroup a, Ring a) => VerifiedRing a where+  total ringOpIsAssociative   : (l, c, r : a) -> l <.> (c <.> r) = (l <.> c) <.> r+  total ringOpIsDistributiveL : (l, c, r : a) -> l <.> (c <+> r) = (l <.> c) <+> (l <.> r)+  total ringOpIsDistributiveR : (l, c, r : a) -> (l <+> c) <.> r = (l <.> r) <+> (c <.> r)++interface (VerifiedRing a, RingWithUnity a) => VerifiedRingWithUnity a where+  total ringWithUnityIsUnityL : (l : a) -> l <.> Algebra.unity = l+  total ringWithUnityIsUnityR : (r : a) -> Algebra.unity <.> r = r++--interface (VerifiedRingWithUnity a, Field a) => VerifiedField a where+--  total fieldInverseIsInverseL : (l : a) -> (notId : Not (l = neutral)) -> l <.> (inverseM l notId) = Algebra.unity+--  total fieldInverseIsInverseR : (r : a) -> (notId : Not (r = neutral)) -> (inverseM r notId) <.> r = Algebra.unity+++interface JoinSemilattice a => VerifiedJoinSemilattice a where+  total joinSemilatticeJoinIsAssociative : (l, c, r : a) -> join l (join c r) = join (join l c) r+  total joinSemilatticeJoinIsCommutative : (l, r : a)    -> join l r = join r l+  total joinSemilatticeJoinIsIdempotent  : (e : a)       -> join e e = e++interface MeetSemilattice a => VerifiedMeetSemilattice a where+  total meetSemilatticeMeetIsAssociative : (l, c, r : a) -> meet l (meet c r) = meet (meet l c) r+  total meetSemilatticeMeetIsCommutative : (l, r : a)    -> meet l r = meet r l+  total meetSemilatticeMeetIsIdempotent  : (e : a)       -> meet e e = e++{- FIXME: Some maintenance required here.+   Algebra.top and Algebra.bottom don't exist!+-}+{-++interface (VerifiedJoinSemilattice a, BoundedJoinSemilattice a) => VerifiedBoundedJoinSemilattice a where+  total boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e Algebra.bottom = e++interface (VerifiedMeetSemilattice a, BoundedMeetSemilattice a) => VerifiedBoundedMeetSemilattice a where+  total boundedMeetSemilatticeTopIsTop : (e : a) -> meet e Algebra.top = e++interface (VerifiedJoinSemilattice a, VerifiedMeetSemilattice a) => VerifiedLattice a where+  total latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l+  total latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l++interface (VerifiedBoundedJoinSemilattice a, VerifiedBoundedMeetSemilattice a, VerifiedLattice a) => VerifiedBoundedLattice a where { }+++--interface (VerifiedRingWithUnity a, VerifiedAbelianGroup b, Module a b) => VerifiedModule a b where+--  total moduleScalarMultiplyComposition : (x,y : a) -> (v : b) -> x <#> (y <#> v) = (x <.> y) <#> v+--  total moduleScalarUnityIsUnity : (v : b) -> Algebra.unity {a} <#> v = v+--  total moduleScalarMultDistributiveWRTVectorAddition : (s : a) -> (v, w : b) -> s <#> (v <+> w) = (s <#> v) <+> (s <#> w)+--  total moduleScalarMultDistributiveWRTModuleAddition : (s, t : a) -> (v : b) -> (s <+> t) <#> v = (s <#> v) <+> (t <#> v)++--interface (VerifiedField a, VerifiedModule a b) => VerifiedVectorSpace a b where {}++-}
libs/contrib/Network/Cgi.idr view
@@ -32,29 +32,29 @@  implementation Functor CGI where     map f (MkCGI c) = MkCGI (\s => do (a, i) <- c s-                                      return (f a, i))+                                      pure (f a, i))  implementation Applicative CGI where-    pure v = MkCGI (\s => return (v, s))+    pure v = MkCGI (\s => pure (v, s))      (MkCGI a) <*> (MkCGI b) = MkCGI (\s => do (f, i) <- a s                                               (c, j) <- b i-                                              return (f c, j))+                                              pure (f c, j))  implementation Monad CGI where     (>>=) (MkCGI f) k = MkCGI (\s => do v <- f s                                         getAction (k (fst v)) (snd v))  setInfo : CGIInfo -> CGI ()-setInfo i = MkCGI (\s => return ((), i))+setInfo i = MkCGI (\s => pure ((), i))  getInfo : CGI CGIInfo-getInfo = MkCGI (\s => return (s, s))+getInfo = MkCGI (\s => pure (s, s))  export lift : IO a -> CGI a lift op = MkCGI (\st => do { x <- op-                             return (x, st) } )+                             pure (x, st) } )  export output : String -> CGI ()@@ -64,30 +64,30 @@ export queryVars : CGI Vars queryVars = do i <- getInfo-               return (GET i)+               pure (GET i)  export postVars : CGI Vars postVars = do i <- getInfo-              return (POST i)+              pure (POST i)  export cookieVars : CGI Vars cookieVars = do i <- getInfo-                return (Cookies i)+                pure (Cookies i)  export queryVar : String -> CGI (Maybe String) queryVar x = do vs <- queryVars-                return (lookup x vs)+                pure (lookup x vs)  getOutput : CGI String getOutput = do i <- getInfo-               return (Output i)+               pure (Output i)  getHeaders : CGI String getHeaders = do i <- getInfo-                return (Headers i)+                pure (Headers i)  export flushHeaders : CGI ()@@ -110,14 +110,14 @@ getContent : Int -> IO String getContent x = getC (cast x) "" where     getC : Nat -> String -> IO String-    getC Z     acc = return $ reverse acc+    getC Z     acc = pure $ reverse acc     getC (S k) acc = do x <- getChar                         getC k (strCons x acc)  getCgiEnv : String -> IO String getCgiEnv key = do   val <- getEnv key-  return $ maybe "" id val+  pure $ maybe "" id val  export runCGI : CGI a -> IO a@@ -138,6 +138,6 @@                  "")     putStrLn (Headers st)     putStr (Output st)-    return v+    pure v  
libs/contrib/Network/Socket.idr view
@@ -219,7 +219,7 @@    if socket_res == -1     then map Left getErrno-    else return $ Right (MkSocket socket_res sf st pn)+    else pure $ Right (MkSocket socket_res sf st pn)  ||| Close a socket export@@ -245,7 +245,7 @@                   (toCode $ socketType sock) (saString addr) port   if bind_res == (-1)     then getErrno-    else return 0+    else pure 0  ||| Connects to a given address and port. ||| Returns 0 on success, and an error number on error.@@ -261,7 +261,7 @@    if conn_res == (-1)     then getErrno-    else return 0+    else pure 0  ||| Listens on a bound socket. |||@@ -273,7 +273,7 @@                     (descriptor sock) BACKLOG   if listen_res == (-1)     then getErrno-    else return 0+    else pure 0  ||| Parses a textual representation of an IPv4 address into a SocketAddress parseIPv4 : String -> SocketAddress@@ -305,9 +305,9 @@                            (Ptr -> IO String)                            ptr -      return $ parseIPv4 ipv4_addr-    Just AF_INET6 => return IPv6Addr-    Just AF_UNSPEC => return InvalidAddress)+      pure $ parseIPv4 ipv4_addr+    Just AF_INET6 => pure IPv6Addr+    Just AF_UNSPEC => pure InvalidAddress)  ||| Accept a connection on the provided socket. |||@@ -337,7 +337,7 @@       let (MkSocket _ fam ty p_num) = sock       sockaddr <- getSockAddr (SAPtr sockaddr_ptr)       sockaddr_free (SAPtr sockaddr_ptr)-      return $ Right ((MkSocket accept_res fam ty p_num), sockaddr)+      pure $ Right ((MkSocket accept_res fam ty p_num), sockaddr)  ||| Send data on the specified socket. |||@@ -357,7 +357,7 @@    if send_res == (-1)     then map Left getErrno-    else return $ Right send_res+    else pure $ Right send_res  freeRecvStruct : RecvStructPtr -> IO () freeRecvStruct (RSPtr p) =@@ -400,18 +400,18 @@     then do       errno <- getErrno       freeRecvStruct (RSPtr recv_struct_ptr)-      return $ Left errno+      pure $ Left errno     else       if recv_res == 0         then do            freeRecvStruct (RSPtr recv_struct_ptr)-           return $ Left 0+           pure $ Left 0         else do            payload <- foreign FFI_C "idrnet_get_recv_payload"                              (Ptr -> IO String)                              recv_struct_ptr            freeRecvStruct (RSPtr recv_struct_ptr)-           return $ Right (payload, recv_res)+           pure $ Right (payload, recv_res)  ||| Sends the data in a given memory location |||@@ -432,7 +432,7 @@    if send_res == (-1)    then map Left getErrno-   else return $ Right send_res+   else pure $ Right send_res  ||| Receive data from a given memory location. |||@@ -453,7 +453,7 @@    if (recv_res == (-1))     then map Left getErrno-    else return $ Right recv_res+    else pure $ Right recv_res  ||| Send a message. |||@@ -477,7 +477,7 @@    if sendto_res == (-1)     then map Left getErrno-    else return $ Right sendto_res+    else pure $ Right sendto_res  ||| Send a message stored in some buffer. |||@@ -502,7 +502,7 @@    if sendto_res == (-1)     then map Left getErrno-    else return $ Right sendto_res+    else pure $ Right sendto_res  ||| Utility function to get the payload of the sent message as a `String`. foreignGetRecvfromPayload : RecvfromStructPtr -> IO String@@ -528,7 +528,7 @@   port         <- foreign FFI_C "idrnet_sockaddr_ipv4_port"                           (Ptr -> IO Int)                           sockaddr_ptr-  return port+  pure port   ||| Receive a message.@@ -568,7 +568,7 @@           port <- foreignGetRecvfromPort recv_ptr'           addr <- foreignGetRecvfromAddr recv_ptr'           freeRecvfromStruct recv_ptr'-          return $ Right (MkUDPAddrInfo addr port, payload, result)+          pure $ Right (MkUDPAddrInfo addr port, payload, result)  ||| Receive a message placed on a 'known' buffer. |||@@ -606,6 +606,6 @@           port <- foreignGetRecvfromPort recv_ptr'           addr <- foreignGetRecvfromAddr recv_ptr'           freeRecvfromStruct recv_ptr'-          return $ Right (MkUDPAddrInfo addr port, result + 1)+          pure $ Right (MkUDPAddrInfo addr port, result + 1)  -- --------------------------------------------------------------------- [ EOF ]
libs/contrib/System/Concurrency/Process.idr view
@@ -18,7 +18,7 @@      map f (Lift a) = Lift (map f a)  implementation Applicative (Process msg) where-     pure = Lift . return+     pure = Lift . pure      (Lift f) <*> (Lift a) = Lift (f <*> a)  implementation Monad (Process msg) where@@ -32,14 +32,16 @@ ||| Get current process ID export myID : Process msg (ProcID msg)-myID = Lift (return (MkPID prim__vm))+myID = Lift (do me <- getMyVM+                pure (MkPID me))  ||| Send a message to another process ||| Returns whether the send was unsuccessful. export send : ProcID msg -> msg -> Process msg Bool-send (MkPID p) m = Lift (do x <- sendToThread p 0 (prim__vm, m)-                            return (x /= 0))+send (MkPID p) m = Lift (do me <- getMyVM+                            x <- sendToThread p 0 (me, m)+                            pure (x /= 0))  ||| Return whether a message is waiting in the queue export@@ -55,7 +57,7 @@ export recv : Process msg msg recv {msg} = do (senderid, m) <- Lift get-                return m+                pure m   where get : IO (Ptr, msg)         get = getMsg @@ -74,11 +76,11 @@ recvWithSender : Process msg (ProcID msg, msg) recvWithSender {msg}      = do (senderid, m) <- Lift get-          return (MkPID senderid, m)+          pure (MkPID senderid, m)   where get : IO (Ptr, msg)         get = getMsg  export create : Process msg () -> Process msg (ProcID msg) create (Lift p) = do ptr <- Lift (fork p)-                     return (MkPID ptr)+                     pure (MkPID ptr)
libs/contrib/contrib.ipkg view
@@ -5,11 +5,11 @@            Control.Algebra,           Control.Algebra.Lattice, Control.Algebra.VectorSpace,-          Control.Algebra.NumericInstances,+          Control.Algebra.NumericImplementations,           Control.Isomorphism.Primitives,           Control.Partial, -          Classes.Verified,+          Interfaces.Verified,            Data.Fun, Data.Rel,           Data.Hash,
libs/effects/Effect/Memory.idr view
@@ -45,7 +45,7 @@   | True  = do ptr <- ioe_lift $ foreign FFI_C "malloc" (Int -> IO Ptr) (fromInteger $ cast size)                fail  <- ioe_lift $ nullPtr ptr                if fail then ioe_fail "Cannot allocate memory"-               else return ptr+               else pure ptr   | False = ioe_fail "The target architecture does not support adressing enough memory"  private@@ -66,15 +66,15 @@  private do_peek : Ptr -> Nat -> (size : Nat) -> IO (Vect size Bits8)-do_peek _   _       Z = return (Vect.Nil)+do_peek _   _       Z = pure (Vect.Nil) do_peek ptr offset (S n)   = do b <- foreign FFI_C "idris_peek" (Ptr -> Int -> IO Bits8) ptr (fromInteger $ cast offset)        bs <- do_peek ptr (S offset) n-       Monad.return (Vect.(::) b bs)+       Applicative.pure (Vect.(::) b bs)  private do_poke : Ptr -> Nat -> Vect size Bits8 -> IO ()-do_poke _   _      []     = return ()+do_poke _   _      []     = pure () do_poke ptr offset (b::bs)   = do foreign FFI_C "idris_poke" (Ptr -> Int -> Bits8 -> IO ()) ptr (fromInteger $ cast offset) b        do_poke ptr (S offset) bs@@ -179,5 +179,5 @@ move dst_offset src_offset size dst_bounds src_bounds   = do src_ptr <- Src :- getRawPtr        Dst :- move' src_ptr dst_offset src_offset size dst_bounds src_bounds-       return ()+       pure () 
libs/effects/Effect/Perf.idr view
@@ -106,7 +106,7 @@ perfLog res msg =     if livePerf res       then putStrLn $ unwords ["PERF:", msg]-      else return ()+      else pure ()  -- ------------------------------------------------------- [ Effect Definition ] 
libs/effects/Effect/Random.idr view
@@ -21,14 +21,14 @@ ||| Generates a random Integer in a given range rndInt : Integer -> Integer -> Eff Integer [RND] rndInt lower upper = do v <- call $ GetRandom-                        return ((v `prim__sremBigInt` (upper - lower)) + lower)+                        pure ((v `prim__sremBigInt` (upper - lower)) + lower)  ||| Generate a random number in Fin (S `k`) |||  ||| Note that rndFin k takes values 0, 1, ..., k. rndFin : (k : Nat) -> Eff (Fin (S k)) [RND] rndFin k = do let v = assert_total $ !(call GetRandom) `prim__sremBigInt` (cast (S k))-              return (toFin v)+              pure (toFin v)  where toFin : Integer -> Fin (S k)         toFin x = case integerToFin x (S k) of                       Just v => v@@ -36,12 +36,12 @@  ||| Select a random element from a vector rndSelect' : Vect (S k) a -> Eff a [RND]-rndSelect' {k} xs = return (Vect.index !(rndFin k)  xs)+rndSelect' {k} xs = pure (Vect.index !(rndFin k)  xs)  ||| Select a random element from a list, or Nothing if the list is empty rndSelect : List a -> Eff (Maybe a) [RND]-rndSelect []      = return Nothing-rndSelect (x::xs) = return (Just !(rndSelect' (x::(fromList xs))))+rndSelect []      = pure Nothing+rndSelect (x::xs) = pure (Just !(rndSelect' (x::(fromList xs))))  ||| Sets the random seed srand : Integer -> Eff () [RND]
libs/effects/Effect/State.idr view
@@ -36,5 +36,5 @@                         putM newst                         val <- prog                         putM st-                        return val+                        pure val 
libs/effects/Effects.idr view
@@ -303,16 +303,16 @@ toEff : .(xs' : List EFFECT) -> EffM m a xs (\v => xs') -> EffM m a xs (\v => xs') toEff xs' = id -return : a -> EffM m a xs (\v => xs)-return x = Value x---- ------------------------------------------------------ [ for idiom brackets ]- infixl 2 <*>  pure : a -> EffM m a xs (\v => xs) pure = Value +return : a -> EffM m a xs (\v => xs)+return = pure++%deprecate Effects.return "Please use `pure`."+ pureM : (val : a) -> EffM m a (xs val) xs pureM = Value @@ -320,7 +320,7 @@         EffM m a xs (\v => xs) -> EffM m b xs (\v => xs) (<*>) prog v = do fn <- prog                   arg <- v-                  return (fn arg)+                  pure (fn arg)  (<$>) : (a -> b) ->         EffM m a xs (\v => xs) -> EffM m b xs (\v => xs)@@ -366,7 +366,7 @@    = let env' = unlabel env in          eff env' prog (\p', envk => k p' (relabel l envk)) --- yuck :) Haven't got interface instances working nicely in tactic+-- yuck :) Haven't got interface implementations working nicely in tactic -- proofs yet, and 'search' can't be told about any hints yet, -- so just brute force it. syntax MkDefaultEnv = with Env
+ libs/oldeffects/Effect/Default.idr view
@@ -0,0 +1,44 @@+module Default++interface Default a where+    default : a++implementation Default Int where+    default = 0++implementation Default Integer where+    default = 0++implementation Default Double where+    default = 0++implementation Default Nat where+    default = 0++implementation Default Char where+    default = '\0'++implementation Default String where+    default = ""++implementation Default Bool where+    default = False++implementation Default () where+    default = ()++implementation (Default a, Default b) => Default (a, b) where+    default = (default, default)++implementation Default (Maybe a) where+    default = Nothing++implementation Default (List a) where+    default = []++implementation Default a => Default (Vect n a) where+    default = mkDef _ where+      mkDef : (n : Nat) -> Vect n a+      mkDef Z = []+      mkDef (S k) = default :: mkDef k+
+ libs/oldeffects/Effect/Exception.idr view
@@ -0,0 +1,41 @@+module Effect.Exception++import Effects+import System+import Control.IOExcept++data Exception : Type -> Effect where+     Raise : a -> { () } Exception a b++implementation Handler (Exception a) Maybe where+     handle _ (Raise e) k = Nothing++implementation Handler (Exception a) List where+     handle _ (Raise e) k = []++implementation Show a => Handler (Exception a) IO where+     handle _ (Raise e) k = do printLn e+                               believe_me (exit 1)++implementation Handler (Exception a) (IOExcept a) where+     handle _ (Raise e) k = ioM (pure (Left e))++implementation Handler (Exception a) (Either a) where+     handle _ (Raise e) k = Left e++EXCEPTION : Type -> EFFECT+EXCEPTION t = MkEff () (Exception t)++raise : a -> { [EXCEPTION a ] } Eff m b+raise err = call $ Raise err+++++++-- TODO: Catching exceptions mid program?+-- probably need to invoke a new interpreter++-- possibly add a 'handle' to the Eff language so that an alternative+-- handler can be introduced mid interpretation?
+ libs/oldeffects/Effect/File.idr view
@@ -0,0 +1,128 @@+-- -------------------------------------------------------- [ Effectful FileIO ]+module Effect.File++import Effects+import Control.IOExcept+++||| A Dependent type to describe File Handles. File handles are+||| parameterised with the current state of the file: Closed; Open for+||| reading; and Open for writing.+||| +||| @ m The file mode. +data OpenFile : (m : Mode) -> Type where+     FH : File -> OpenFile m++openOK : Mode -> Bool -> Type+openOK m True = OpenFile m+openOK m False = ()++-- ------------------------------------------------------------ [ The Protocol ]++||| Here the protocol for resource access is defined as an effect.+||| The state transitions diagram for the protocol is as follows:+||| +|||     digraph G {+||| +|||       empty; read; write; // States+||| +|||       empty -> read [label="Open R"];+|||       read -> empty [label="Close"];+|||       read -> read [label="ReadLine"];+|||       read -> read [label="EOF"];+|||           +|||       empty -> write [label="Open W"];+|||       write -> empty [label="Close"];+|||       write -> write [label="WriteLine"];+||| +|||     }+data FileIO : Effect where+  ||| Open a file with the specified mode.+  ||| +  ||| Opening a file successful moves the state from 'empty' to the+  ||| specified mode. If not successful the state is still 'empty'.+  ||| +  ||| @ fname The file name to be opened.+  ||| @ m The file mode.+  Open : (fname: String)+         -> (m : Mode)+         -> {() ==> {res} if res+                             then OpenFile m+                             else ()} FileIO Bool++  ||| Close a file.+  ||| +  ||| Closing a file moves the state from Open to closed.+  Close : {OpenFile m ==> ()} FileIO () ++  ||| Read a line from the file.+  ||| +  ||| Only files that are open for reading can be read.+  ReadLine : {OpenFile Read}  FileIO String +  +  ||| Write a line to a file.+  ||| +  ||| Only file that are open for writing can be written to.+  WriteLine : String -> {OpenFile Write} FileIO ()++  ||| End of file?+  ||| +  ||| Only files open for reading can be tested for EOF+  EOF : {OpenFile Read}  FileIO Bool++-- ------------------------------------------------------------ [ The Handlers ]++--- An implementation of the resource access protocol for the IO Context.+implementation Handler FileIO IO where+    handle () (Open fname m) k = do h <- openFile fname m+                                    valid <- validFile h+                                    if valid then k True (FH h) +                                             else k False ()+    handle (FH h) Close      k = do closeFile h+                                    k () ()+    handle (FH h) ReadLine        k = do str <- fread h+                                         k str (FH h)+    handle (FH h) (WriteLine str) k = do fwrite h str+                                         k () (FH h)+    handle (FH h) EOF             k = do e <- feof h+                                         k e (FH h)++-- -------------------------------------------------------------- [ The Effect ]+FILE_IO : Type -> EFFECT+FILE_IO t = MkEff t FileIO++-- ------------------------------------------------------------ [ The Bindings ]+--+-- Bind the IO context handlers to functions. These functions will run+-- in the IO context.+--++||| Open a file with the specified mode.+||| +||| @ fname The file name to be opened.+||| @ m The file mode.+open : (fname : String)+       -> (m : Mode)+       -> { [FILE_IO ()] ==> [FILE_IO (if result+                                          then OpenFile m+                                          else ())] } Eff e Bool+open f m = call $ Open f m+++||| Close a file.+close : { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()+close = call $ Close++||| Read a line from the file.+readLine : { [FILE_IO (OpenFile Read)] } Eff e String +readLine = call $ ReadLine++||| Write a line to a file.+writeLine : String -> { [FILE_IO (OpenFile Write)] } Eff e ()+writeLine str = call $ WriteLine str++||| End of file?+eof : { [FILE_IO (OpenFile Read)] } Eff e Bool +eof = call $ EOF++-- --------------------------------------------------------------------- [ EOF ]
+ libs/oldeffects/Effect/Memory.idr view
@@ -0,0 +1,175 @@+module Effect.Memory++import Effects+import Control.IOExcept++%access public++abstract+data MemoryChunk : Nat -> Nat -> Type where+     CH : Ptr -> MemoryChunk size initialized++abstract+data RawMemory : Effect where+     Allocate   : (n : Nat) ->+                  RawMemory () () (\v => MemoryChunk n 0)+     Free       : RawMemory () (MemoryChunk n i) (\v => ())+     Initialize : Bits8 ->+                  (size : Nat) ->+                  so (i + size <= n) ->+                  RawMemory () (MemoryChunk n i) (\v => MemoryChunk n (i + size))+     Peek       : (offset : Nat) ->+                  (size : Nat) ->+                  so (offset + size <= i) ->+                  RawMemory (Vect size Bits8)+                            (MemoryChunk n i) (\v => MemoryChunk n i) +     Poke       :  (offset : Nat) ->+                  (Vect size Bits8) ->+                  so (offset <= i && offset + size <= n) ->+                  RawMemory () (MemoryChunk n i) (\v => MemoryChunk n (max i (offset + size))) +     Move       : (src : MemoryChunk src_size src_init) ->+                  (dst_offset : Nat) ->+                  (src_offset : Nat) ->+                  (size : Nat) ->+                  so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->+                  so (src_offset + size <= src_init) ->+                  RawMemory () (MemoryChunk dst_size dst_init)+                            (\v => MemoryChunk dst_size (max dst_init (dst_offset + size))) +     GetRawPtr  : RawMemory (MemoryChunk n i) (MemoryChunk n i) (\v => MemoryChunk n i) ++private+do_malloc : Nat -> IOExcept String Ptr+do_malloc size with (fromInteger (cast size) == size)+  | True  = do ptr <- ioe_lift $ mkForeign (FFun "malloc" [FInt] FPtr) (fromInteger $ cast size)+               fail  <- ioe_lift $ nullPtr ptr+               if fail then ioe_fail "Cannot allocate memory"+               else pure ptr+  | False = ioe_fail "The target architecture does not support adressing enough memory"++private+do_memset : Ptr -> Nat -> Bits8 -> Nat -> IO ()+do_memset ptr offset c size+  = mkForeign (FFun "idris_memset" [FPtr, FInt, FByte, FInt] FUnit)+              ptr (fromInteger $ cast offset) c (fromInteger $ cast size)++private+do_free : Ptr -> IO ()+do_free ptr = mkForeign (FFun "free" [FPtr] FUnit) ptr++private+do_memmove : Ptr -> Ptr -> Nat -> Nat -> Nat -> IO ()+do_memmove dest src dest_offset src_offset size+  = mkForeign (FFun "idris_memmove" [FPtr, FPtr, FInt, FInt, FInt] FUnit)+              dest src (fromInteger $ cast dest_offset) (fromInteger $ cast src_offset) (fromInteger $ cast size)++private+do_peek : Ptr -> Nat -> (size : Nat) -> IO (Vect size Bits8)+do_peek _   _       Z = pure (Prelude.Vect.Nil)+do_peek ptr offset (S n)+  = do b <- mkForeign (FFun "idris_peek" [FPtr, FInt] FByte) ptr (fromInteger $ cast offset)+       bs <- do_peek ptr (S offset) n+       Prelude.Applicative.pure (Prelude.Vect.(::) b bs)++private+do_poke : Ptr -> Nat -> Vect size Bits8 -> IO ()+do_poke _   _      []     = pure ()+do_poke ptr offset (b::bs)+  = do mkForeign (FFun "idris_poke" [FPtr, FInt, FByte] FUnit) ptr (fromInteger $ cast offset) b+       do_poke ptr (S offset) bs++implementation Handler RawMemory (IOExcept String) where+  handle () (Allocate n) k+    = do ptr <- do_malloc n+         k () (CH ptr)+  handle {-{res = MemoryChunk _ offset}-} (CH ptr) (Initialize {i} c size _) k+    = ioe_lift (do_memset ptr i c size) $> k () (CH ptr)+  handle (CH ptr) (Free) k+    = ioe_lift (do_free ptr) $> k () ()+  handle (CH ptr) (Peek offset size _) k+    = do res <- ioe_lift (do_peek ptr offset size)+         k res (CH ptr)+  handle (CH ptr) (Poke offset content _) k+    = do ioe_lift (do_poke ptr offset content)+         k () (CH ptr)+  handle (CH dest_ptr) (Move (CH src_ptr) dest_offset src_offset size _ _) k+    = do ioe_lift (do_memmove dest_ptr src_ptr dest_offset src_offset size)+         k () (CH dest_ptr)+  handle chunk (GetRawPtr) k+    = k chunk chunk++RAW_MEMORY : Type -> EFFECT+RAW_MEMORY t = MkEff t RawMemory++allocate : (n : Nat) -> +           Eff m () [RAW_MEMORY ()] (\v => [RAW_MEMORY (MemoryChunk n 0)])+allocate size = call $ Allocate size++initialize : {i : Nat} ->+             {n : Nat} ->+             Bits8 ->+             (size : Nat) ->+             so (i + size <= n) ->+             Eff m () [RAW_MEMORY (MemoryChunk n i)] +                       (\v => [RAW_MEMORY (MemoryChunk n (i + size))])+initialize c size prf = call $ Initialize c size prf++free : Eff m () [RAW_MEMORY (MemoryChunk n i)] (\v => [RAW_MEMORY ()])+free = call Free++peek : {i : Nat} ->+       (offset : Nat) ->+       (size : Nat) ->+       so (offset + size <= i) ->+       { [RAW_MEMORY (MemoryChunk n i)] } Eff m (Vect size Bits8) +peek offset size prf = call $ Peek offset size prf++poke : {n : Nat} ->+       {i : Nat} ->+       (offset : Nat) ->+       Vect size Bits8 ->+       so (offset <= i && offset + size <= n) ->+       Eff m () [RAW_MEMORY (MemoryChunk n i)] +              (\v => [RAW_MEMORY (MemoryChunk n (max i (offset + size)))])+poke offset content prf = call $ Poke offset content prf++private+getRawPtr : { [RAW_MEMORY (MemoryChunk n i)] } Eff m (MemoryChunk n i) +getRawPtr = call $ GetRawPtr++private+move' : {dst_size : Nat} ->+        {dst_init : Nat} ->+        {src_init : Nat} ->+        (src_ptr : MemoryChunk src_size src_init) ->+        (dst_offset : Nat) ->+        (src_offset : Nat) ->+        (size : Nat) ->+        so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->+        so (src_offset + size <= src_init) ->+        Eff m () [RAW_MEMORY (MemoryChunk dst_size dst_init)]+               (\v => [RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))])+move' src_ptr dst_offset src_offset size dst_bounds src_bounds+  = call $ Move src_ptr dst_offset src_offset size dst_bounds src_bounds++data MoveDescriptor = Dst | Src++move : {dst_size : Nat} ->+       {dst_init : Nat} ->+       {src_size : Nat} ->+       {src_init : Nat} ->+       (dst_offset : Nat) ->+       (src_offset : Nat) ->+       (size : Nat) ->+       so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->+       so (src_offset + size <= src_init) ->+       Eff m ()+              [ Dst ::: RAW_MEMORY (MemoryChunk dst_size dst_init)+              , Src ::: RAW_MEMORY (MemoryChunk src_size src_init)]+              (\v =>+                [ Dst ::: RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))+                , Src ::: RAW_MEMORY (MemoryChunk src_size src_init)])+move dst_offset src_offset size dst_bounds src_bounds+  = do src_ptr <- Src :- getRawPtr+       Dst :- move' src_ptr dst_offset src_offset size dst_bounds src_bounds+       pure ()+
+ libs/oldeffects/Effect/Monad.idr view
@@ -0,0 +1,21 @@+module Effect.Monad++import Effects++-- Eff is a monad too, so we can happily use it in a monad transformer.++using (xs : List EFFECT, m : Type -> Type)+  implementation Functor (\a => EffM m a xs (\v => xs)) where+    map f prog = do t <- prog+                    value (f t)++  implementation Applicative (\a => EffM m a xs (\v => xs)) where+    pure = value+    (<*>) f a = do f' <- f+                   a' <- a+                   value (f' a')++  implementation Monad (\a => Eff m a xs (\v => xs)) where+    (>>=) = Effects.(>>=)++
+ libs/oldeffects/Effect/Random.idr view
@@ -0,0 +1,47 @@+module Effect.Random++import Effects++data Random : Effect where +     getRandom : { Integer } Random Integer +     setSeed   : Integer -> { Integer } Random () ++using (m : Type -> Type)+  implementation Handler Random m where+     handle seed getRandom k+              = let seed' = assert_total ((1664525 * seed + 1013904223) `prim__sremBigInt` (pow 2 32)) in+                    k seed' seed'+     handle seed (setSeed n) k = k () n++RND : EFFECT+RND = MkEff Integer Random++||| Generates a random Integer in a given range+rndInt : Integer -> Integer -> { [RND] } Eff m Integer+rndInt lower upper = do v <- call $ getRandom+                        pure (v `prim__sremBigInt` (upper - lower) + lower)++||| Generate a random number in Fin (S `k`)+||| +||| Note that rndFin k takes values 0, 1, ..., k.+rndFin : (k : Nat) -> { [RND] } Eff m (Fin (S k))+rndFin k = do let v = assert_total $ !(call getRandom) `prim__sremBigInt` (cast (S k))+              pure (toFin v)+ where toFin : Integer -> Fin (S k) +       toFin x = case integerToFin x (S k) of+                      Just v => v+                      Nothing => toFin (assert_smaller x (x - cast (S k)))++||| Select a random element from a vector+rndSelect' : Vect (S k) a -> { [RND] } Eff IO a+rndSelect' {k} xs = pure (Vect.index !(rndFin k)  xs)++||| Select a random element from a list, or Nothing if the list is empty+rndSelect : List a -> { [RND] } Eff IO (Maybe a)+rndSelect []      = pure Nothing+rndSelect (x::xs) = pure (Just !(rndSelect' (x::(fromList xs))))++||| Sets the random seed+srand : Integer -> { [RND] } Eff m ()+srand n = call $ setSeed n+
+ libs/oldeffects/Effect/Select.idr view
@@ -0,0 +1,23 @@+module Effect.Select++import Effects++data Selection : Effect where+     Select : List a -> { () } Selection a ++implementation Handler Selection Maybe where+     handle _ (Select xs) k = tryAll xs where+         tryAll [] = Nothing+         tryAll (x :: xs) = case k x () of+                                 Nothing => tryAll xs+                                 Just v => Just v++implementation Handler Selection List where+     handle r (Select xs) k = concatMap (\x => k x r) xs++SELECT : EFFECT+SELECT = MkEff () Selection++select : List a -> { [SELECT] } Eff m a +select xs = call $ Select xs+
+ libs/oldeffects/Effect/State.idr view
@@ -0,0 +1,40 @@+module Effect.State++import Effects++%access public++data State : Effect where+  Get :      { a }       State a+  Put : b -> { a ==> b } State () ++using (m : Type -> Type)+  implementation Handler State m where+     handle st Get     k = k st st+     handle st (Put n) k = k () n++STATE : Type -> EFFECT+STATE t = MkEff t State++get : { [STATE x] } Eff m x+get = call $ Get++put : x -> { [STATE x] } Eff m () +put val = call $ Put val++putM : y -> { [STATE x] ==> [STATE y] } Eff m () +putM val = call $ Put val++update : (x -> x) -> { [STATE x] } Eff m () +update f = put (f !get)++updateM : (x -> y) -> { [STATE x] ==> [STATE y] } Eff m () +updateM f = putM (f !get)++locally : x -> ({ [STATE x] } Eff m t) -> { [STATE y] } Eff m t +locally newst prog = do st <- get+                        putM newst+                        val <- prog+                        putM st+                        pure val+
+ libs/oldeffects/Effect/StdIO.idr view
@@ -0,0 +1,60 @@+module Effect.StdIO++import Effects+import Control.IOExcept++-------------------------------------------------------------+-- IO effects internals+-------------------------------------------------------------++||| The internal representation of StdIO effects+data StdIO : Effect where+     PutStr : String -> { () } StdIO () +     GetStr : { () } StdIO String +     PutCh : Char -> { () } StdIO ()+     GetCh : { () } StdIO Char+++-------------------------------------------------------------+-- IO effects handlers+-------------------------------------------------------------++implementation Handler StdIO IO where+    handle () (PutStr s) k = do putStr s; k () ()+    handle () GetStr     k = do x <- getLine; k x ()+    handle () (PutCh c)  k = do putChar c; k () () +    handle () GetCh      k = do x <- getChar; k x ()++implementation Handler StdIO (IOExcept a) where+    handle () (PutStr s) k = do ioe_lift $ putStr s; k () ()+    handle () GetStr     k = do x <- ioe_lift $ getLine; k x ()+    handle () (PutCh c)  k = do ioe_lift $ putChar c; k () () +    handle () GetCh      k = do x <- ioe_lift $ getChar; k x ()++-------------------------------------------------------------+--- The Effect and associated functions+-------------------------------------------------------------++STDIO : EFFECT+STDIO = MkEff () StdIO++||| Write a string to standard output.+putStr : String -> { [STDIO] } Eff e ()+putStr s = call $ PutStr s++||| Write a character to standard output.+putChar : Char -> { [STDIO] } Eff e ()+putChar c = call $ PutCh c++||| Write a string to standard output, terminating with a newline.+putStrLn : String -> { [STDIO] } Eff e ()+putStrLn s = putStr (s ++ "\n")++||| Read a string from standard input.+getStr : { [STDIO] } Eff e String+getStr = call $ GetStr++||| Read a character from standard input.+getChar : { [STDIO] } Eff e Char+getChar = call $ GetCh+
+ libs/oldeffects/Effect/System.idr view
@@ -0,0 +1,43 @@+module Effect.System++-- Various system interaction features (this is not necessarily the right way+-- to split them up, I just need some of them now :))++import Effects+import System+import Control.IOExcept++data System : Effect where+     Args : { () } System (List String)+     Time : { () } System Int+     GetEnv : String -> { () } System (Maybe String)+     CSystem : String -> { () } System Int++implementation Handler System IO where+    handle () Args k = do x <- getArgs; k x ()+    handle () Time k = do x <- time; k x ()+    handle () (GetEnv s) k = do x <- getEnv s; k x ()+    handle () (CSystem s) k = do x <- system s; k x ()++implementation Handler System (IOExcept a) where+    handle () Args k = do x <- ioe_lift getArgs; k x ()+    handle () Time k = do x <- ioe_lift time; k x ()+    handle () (GetEnv s) k = do x <- ioe_lift $ getEnv s; k x ()+    handle () (CSystem s) k = do x <- ioe_lift $ system s; k x ()++--- The Effect and associated functions++SYSTEM : EFFECT+SYSTEM = MkEff () System++getArgs : Handler System e => { [SYSTEM] } Eff e (List String)+getArgs = call Args++time : Handler System e => { [SYSTEM] } Eff e Int+time = call Time++getEnv : Handler System e => String -> { [SYSTEM] } Eff e (Maybe String)+getEnv s = call $ GetEnv s++system : Handler System e => String -> { [SYSTEM] } Eff e Int+system s = call $ CSystem s
+ libs/oldeffects/Effects.idr view
@@ -0,0 +1,333 @@+module Effects++import Language.Reflection+import Control.Catchable+import Effect.Default++--- Effectful computations are described as algebraic data types that+--- explain how an effect is interpreted in some underlying context.++%access public+-- ----------------------------------------------------------------- [ Effects ]+||| The Effect type describes effectful computations.+|||+||| This type is parameterised by:+||| + The input resource.+||| + The return type of the computation.+||| + The computation to run on the resource.+Effect : Type+Effect = (x : Type) -> Type -> (x -> Type) -> Type++||| The `EFFECT` Data type describes how to promote the Effect+||| description into a concrete effect.+%error_reverse+data EFFECT : Type where+     MkEff : Type -> Effect -> EFFECT++||| Handler interfaces describe how an effect `e` is translated to the+||| underlying computation context `m` for execution.+interface Handler (e : Effect) (m : Type -> Type) where+  ||| How to handle the effect.+  |||+  ||| @ r The resource being handled.+  ||| @ eff The effect to be applied.+  ||| @ k The continuation to pass the result of the effect+  covering handle : (r : res) -> (eff : e t res resk) ->+                    (k : ((x : t) -> resk x -> m a)) -> m a++||| Get the resource type (handy at the REPL to find out about an effect)+resourceType : EFFECT -> Type+resourceType (MkEff t e) = t++-- --------------------------------------------------------- [ Syntactic Sugar ]++-- A bit of syntactic sugar ('syntax' is not very flexible so we only go+-- up to a small number of parameters...)++-- No state transition+syntax "{" [inst] "}" [eff] = eff inst (\result => inst)++-- The state transition is dependent on a result `b`, a bound variable.+syntax "{" [inst] "==>" "{" {b} "}" [outst] "}" [eff]+       = eff inst (\b => outst)++--- A simple state transition+syntax "{" [inst] "==>" [outst] "}" [eff] = eff inst (\result => outst)++-- --------------------------------------- [ Properties and Proof Construction ]+using (xs : List a, ys : List a)+  data SubList : List a -> List a -> Type where+       SubNil : SubList {a} [] []+       Keep   : SubList xs ys -> SubList (x :: xs) (x :: ys)+       Drop   : SubList xs ys -> SubList xs (x :: ys)++  subListId : SubList xs xs+  subListId {xs = Nil} = SubNil+  subListId {xs = x :: xs} = Keep subListId++namespace Env+  data Env  : (m : Type -> Type) -> List EFFECT -> Type where+       Nil  : Env m Nil+       (::) : Handler eff m => a -> Env m xs -> Env m (MkEff a eff :: xs)++data EffElem : Effect -> Type ->+               List EFFECT -> Type where+     Here : EffElem x a (MkEff a x :: xs)+     There : EffElem x a xs -> EffElem x a (y :: xs)++||| make an environment corresponding to a sub-list+dropEnv : Env m ys -> SubList xs ys -> Env m xs+dropEnv [] SubNil = []+dropEnv (v :: vs) (Keep rest) = v :: dropEnv vs rest+dropEnv (v :: vs) (Drop rest) = dropEnv vs rest++updateWith : (ys' : List a) -> (xs : List a) ->+             SubList ys xs -> List a+updateWith (y :: ys) (x :: xs) (Keep rest) = y :: updateWith ys xs rest+updateWith ys        (x :: xs) (Drop rest) = x :: updateWith ys xs rest+updateWith []        []        SubNil      = []+updateWith (y :: ys) []        SubNil      = y :: ys+updateWith []        (x :: xs) (Keep rest) = []++||| Put things back, replacing old with new in the sub-environment+rebuildEnv : Env m ys' -> (prf : SubList ys xs) ->+             Env m xs -> Env m (updateWith ys' xs prf)+rebuildEnv []        SubNil      env = env+rebuildEnv (x :: xs) SubNil      env = x :: xs+rebuildEnv []        (Keep rest) (y :: env) = []+rebuildEnv (x :: xs) (Keep rest) (y :: env) = x :: rebuildEnv xs rest env+rebuildEnv xs        (Drop rest) (y :: env) = y :: rebuildEnv xs rest env+++-- -------------------------------------------------- [ The Effect EDSL itself ]++updateResTy : (val : t) ->+              (xs : List EFFECT) -> EffElem e a xs -> e t a b ->+              List EFFECT+updateResTy {b} val (MkEff a e :: xs) Here n = (MkEff (b val) e) :: xs+updateResTy     val (x :: xs)    (There p) n = x :: updateResTy val xs p n++infix 5 :::, :-, :=++data LRes : lbl -> Type -> Type where+     (:=) : (x : lbl) -> res -> LRes x res++(:::) : lbl -> EFFECT -> EFFECT+(:::) {lbl} x (MkEff r e) = MkEff (LRes x r) e++using (lbl : Type)+  implementation Default a => Default (LRes lbl a) where+    default = lbl := default++private+unlabel : {l : ty} -> Env m [l ::: x] -> Env m [x]+unlabel {m} {x = MkEff a eff} [l := v] = [v]++private+relabel : (l : ty) -> Env m xs -> Env m (map (\x => l ::: x) xs)+relabel {xs = []} l [] = []+relabel {xs = (MkEff a e :: xs)} l (v :: vs) = (l := v) :: relabel l vs++-- ------------------------------------------------- [ The Language of Effects ]+||| Definition of an Effect.+|||+||| @ m The computation context+||| @ x The return type of the result.+||| @ es The list of allowed side-effects.+||| @ ce Function to compute a new list of allowed side-effects.+data Eff : (m : Type -> Type)+           -> (x : Type)+           -> (es : List EFFECT)+           -> (ce : x -> List EFFECT) -> Type where+     value    : a -> Eff m a xs (\v => xs)+     with_val : (val : a) -> Eff m () xs (\v => xs' val) ->+                Eff m a xs xs'+     ebind    : Eff m a xs xs' ->+                ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''+     callP    : (prf : EffElem e a xs) ->+                (eff : e t a b) ->+                Eff m t xs (\v => updateResTy v xs prf eff)++     liftP    : (prf : SubList ys xs) ->+                Eff m t ys ys' -> Eff m t xs (\v => updateWith (ys' v) xs prf)+     newInit  : Handler e m =>+                res ->+                Eff m a (MkEff res e :: xs) (\v => (MkEff res' e :: xs')) ->+                Eff m a xs (\v => xs')+     catch    : Catchable m err =>+                Eff m a xs xs' -> (err -> Eff m a xs xs') ->+                Eff m a xs xs'++     (:-)     : (l : ty) ->+                Eff m t [x] xs' -> -- [x] (\v => xs) ->+                Eff m t [l ::: x] (\v => map (l :::) (xs' v))++(>>=)   : Eff m a xs xs' ->+          ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''+(>>=) = ebind++-- namespace SimpleBind+--   (>>=) : Eff m a xs (\v => xs) ->+--           ((val : a) -> Eff m b xs xs') -> Eff m b xs xs'+--   (>>=) = ebind++||| Run a subprogram which results in an effect state the same as the input.+staticEff : Eff m a xs (\v => xs) -> Eff m a xs (\v => xs)+staticEff = id++||| Explicitly give the expected set of result effects for an effectful+||| operation.+toEff : .(xs' : List EFFECT) -> Eff m a xs (\v => xs') -> Eff m a xs (\v => xs')+toEff xs' = id++return : a -> Eff m a xs (\v => xs)+return x = value x++-- ------------------------------------------------------ [ for idiom brackets ]++infixl 2 <*>++pure : a -> Eff m a xs (\v => xs)+pure = value++syntax pureM [val] = with_val val (pure ())++(<*>) : Eff m (a -> b) xs (\v => xs) ->+        Eff m a xs (\v => xs) -> Eff m b xs (\v => xs)+(<*>) prog v = do fn <- prog+                  arg <- v+                  return (fn arg)++-- ---------------------------------------------------------- [ an interpreter ]++private+execEff : Env m xs -> (p : EffElem e res xs) ->+          (eff : e a res resk) ->+          ((v : a) -> Env m (updateResTy v xs p eff) -> m t) -> m t+execEff (val :: env) Here eff' k+    = handle val eff' (\v, res => k v (res :: env))+-- FIXME: Teach the elaborator to propagate parameters here+execEff {e} {a} {res} {resk} (val :: env) (There p) eff k+    = execEff {e} {a} {res} {resk} env p eff (\v, env' => k v (val :: env'))++-- Q: Instead of m b, implement as StateT (Env m xs') m b, so that state+-- updates can be propagated even through failing computations?++eff : Env m xs -> Eff m a xs xs' -> ((x : a) -> Env m (xs' x) -> m b) -> m b+eff env (value x) k = k x env+eff env (with_val x prog) k = eff env prog (\p', env' => k x env')+eff env (prog `ebind` c) k+   = eff env prog (\p', env' => eff env' (c p') k)+eff env (callP prf effP) k = execEff env prf effP k+eff env (liftP prf effP) k+   = let env' = dropEnv env prf in+         eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))+eff env (newInit r prog) k+   = eff (r :: env) prog (\p' => \ (v :: envk) => k p' envk)+eff env (catch prog handler) k+   = catch (eff env prog k)+           (\e => eff env (handler e) k)+-- FIXME:+-- xs is needed explicitly because otherwise the pattern binding for+-- 'l' appears too late. Solution seems to be to reorder patterns at the+-- end so that everything is in scope when it needs to be.+eff {xs = [l ::: x]} env (l :- prog) k+   = let env' = unlabel env in+         eff env' prog (\p', envk => k p' (relabel l envk))++-- yuck :) Haven't got interface implementations working nicely in tactic+-- proofs yet, and 'search' can't be told about any hints yet,+-- so just brute force it.+syntax MkDefaultEnv = with Env+                       (| [], [default], [default, default],+                          [default, default, default],+                          [default, default, default, default],+                          [default, default, default, default, default],+                          [default, default, default, default, default, default],+                          [default, default, default, default, default, default, default],+                          [default, default, default, default, default, default, default, default] |)++call : {a, b: _} -> {e : Effect} ->+       (eff : e t a b) ->+       {auto prf : EffElem e a xs} ->+      Eff m t xs (\v => updateResTy v xs prf eff)+call e {prf} = callP prf e++implicit+lift : Eff m t ys ys' ->+       {auto prf : SubList ys xs} ->+       Eff m t xs (\v => updateWith (ys' v) xs prf)+lift e {prf} = liftP prf e+++new : Handler e m =>+      {default default r : res} ->+      Eff m a (MkEff res e :: xs) (\v => (MkEff res' e :: xs')) ->+      Eff m a xs (\v => xs')+new {r} e = newInit r e++-- --------------------------------------------------------- [ Running Effects ]++||| Run an effectful program.+|||+||| The content (`m`) in which to run the program is taken from the environment in which the program is called.+||| The `env` argument is implicit and initialised automatically.+|||+||| @prog The effectful program to run.+run : Applicative m => {default MkDefaultEnv env : Env m xs} -> (prog : Eff m a xs xs') -> m a+run {env} prog = eff env prog (\r, env => pure r)++||| Run an effectful program in the identity context `id`.+|||+||| A helper function useful for when the given context is 'pure'.+||| The `env` argument is implicit and initialised automatically.+|||+||| @prog The effectful program to run.+runPure : {default MkDefaultEnv env : Env id xs} -> (prog : Eff id a xs xs') -> a+runPure {env} prog = eff env prog (\r, env => r)++||| Run an effectful program with a default value for the environment context.+|||+||| This is useful for when no default value exists for a given resource type.+|||+||| @val The default value for the resource type.+||| @prog The effectful program to run.+runInit : Applicative m => (val : Env m xs) -> (prog : Eff m a xs xs') -> m a+runInit env prog = eff env prog (\r, env => pure r)++||| Run an effectful program in the identity context `id` with a given default value for the environment context.+|||+||| A helper function useful for when the given context is 'pure'.+|||+||| @val The default value for the resource type.+||| @prog The effectful program to run.+runPureInit : (val : Env id xs) -> (prog : Eff id a xs xs') -> a+runPureInit env prog = eff env prog (\r, env => r)++runWith : (a -> m a) -> Env m xs -> Eff m a xs xs' -> m a+runWith inj env prog = eff env prog (\r, env => inj r)++runEnv : Applicative m => Env m xs -> Eff m a xs xs' ->+         m (x : a ** Env m (xs' x))+runEnv env prog = eff env prog (\r, env => pure (r ** env))++-- ----------------------------------------------- [ some higher order things ]++mapE : Applicative m => (a -> {xs} Eff m b) -> List a -> {xs} Eff m (List b)+mapE f []        = pure []+mapE f (x :: xs) = [| f x :: mapE f xs |]+++mapVE : Applicative m =>+          (a -> {xs} Eff m b) ->+          Vect n a ->+          {xs} Eff m (Vect n b)+mapVE f []        = pure []+mapVE f (x :: xs) = [| f x :: mapVE f xs |]+++when : Applicative m => Bool -> Lazy ({xs} Eff m ()) -> {xs} Eff m ()+when True  e = Force e+when False e = pure ()++-- --------------------------------------------------------------------- [ EOF ]
+ libs/oldeffects/Makefile view
@@ -0,0 +1,22 @@+IDRIS := idris++PKG   := effects++build:+	$(IDRIS) --build ${PKG}.ipkg++clean:+	$(IDRIS) --clean ${PKG}.ipkg++install:+	$(IDRIS) --install ${PKG}.ipkg++rebuild: clean build++doc:+	$(IDRIS) --mkdoc ${PKG}.ipkg++doc_clean:+	rm -rf ${PKG}_doc++.PHONY: build clean install rebuild doc doc_clean
+ libs/oldeffects/effects.ipkg view
@@ -0,0 +1,9 @@+package oldeffects++opts    = "--nobasepkgs -i ../prelude -i ../base"+modules = Effects, Effect.Default,++          Effect.Exception, Effect.File, Effect.State,+          Effect.Random, Effect.StdIO, Effect.Select,+          Effect.Memory, Effect.System+
libs/prelude/Builtins.idr view
@@ -204,7 +204,7 @@ %extern prim__readFile : prim__WorldType -> Ptr -> String %extern prim__writeFile : prim__WorldType -> Ptr -> String -> Int -%extern prim__vm : Ptr+%extern prim__vm : prim__WorldType -> Ptr %extern prim__stdin : Ptr %extern prim__stdout : Ptr %extern prim__stderr : Ptr
libs/prelude/IO.idr view
@@ -98,8 +98,8 @@ unsafePerformPrimIO : PrimIO a -> a -- compiled as primitive -prim_io_return : a -> PrimIO a-prim_io_return x = Prim__IO x+prim_io_pure : a -> PrimIO a+prim_io_pure x = Prim__IO x  io_bind : IO' l a -> (a -> IO' l b) -> IO' l b io_bind (MkIO fn) k@@ -107,8 +107,8 @@                     (\ b => case k b of                                  MkIO fkb => fkb w)) -io_return : a -> IO' l a-io_return x = MkIO (\w => prim_io_return x)+io_pure : a -> IO' l a+io_pure x = MkIO (\w => prim_io_pure x)  liftPrimIO : (World -> PrimIO a) -> IO' l a liftPrimIO = MkIO@@ -122,21 +122,21 @@  unsafePerformIO : IO' ffi a -> a unsafePerformIO (MkIO f) = unsafePerformPrimIO-        (prim_io_bind (f (TheWorld prim__TheWorld)) (\ b => prim_io_return b))+        (prim_io_bind (f (TheWorld prim__TheWorld)) (\ b => prim_io_pure b))  prim_read : IO' l String-prim_read = MkIO (\w => prim_io_return (prim__readString (world w)))+prim_read = MkIO (\w => prim_io_pure (prim__readString (world w)))  prim_write : String -> IO' l Int prim_write s-   = MkIO (\w => prim_io_return (prim__writeString (world w) s))+   = MkIO (\w => prim_io_pure (prim__writeString (world w) s))  prim_fread : Ptr -> IO' l String-prim_fread h = MkIO (\w => prim_io_return (prim__readFile (world w) h))+prim_fread h = MkIO (\w => prim_io_pure (prim__readFile (world w) h))  prim_fwrite : Ptr -> String -> IO' l Int prim_fwrite h s-   = MkIO (\w => prim_io_return (prim__writeFile (world w) h s))+   = MkIO (\w => prim_io_pure (prim__writeFile (world w) h s))  --------- The C FFI namespace FFI_C@@ -205,17 +205,21 @@ run__provider (MkIO f) = f (TheWorld prim__TheWorld)  prim_fork : PrimIO () -> PrimIO Ptr-prim_fork x = prim_io_return prim__vm -- compiled specially+prim_fork x = prim_io_pure (prim__vm prim__TheWorld) -- compiled specially  namespace IO   fork : IO' l () -> IO' l Ptr   fork (MkIO f) = MkIO (\w => prim_io_bind                                 (prim_fork (prim_io_bind (f w)-                                     (\ x => prim_io_return x)))-                                (\x => prim_io_return x))+                                     (\ x => prim_io_pure x)))+                                (\x => prim_io_pure x)) +  getMyVM : IO' l Ptr+  getMyVM = MkIO (\w => prim_io_pure (prim__vm (world w)))+   forceGC : IO ()-  forceGC = foreign FFI_C "idris_forceGC" (Ptr -> IO ()) prim__vm+  forceGC = io_bind getMyVM+               (\vm => foreign FFI_C "idris_forceGC" (Ptr -> IO ()) vm)    getErrno : IO Int   getErrno = foreign FFI_C "idris_errno" (IO Int)@@ -316,52 +320,52 @@  -- Accessing memory prim_peek8 : Ptr -> Int -> IO Bits8-prim_peek8 ptr offset = MkIO (\w => prim_io_return (prim__peek8 (world w) ptr offset))+prim_peek8 ptr offset = MkIO (\w => prim_io_pure (prim__peek8 (world w) ptr offset))  prim_poke8 : Ptr -> Int -> Bits8 -> IO Int-prim_poke8 ptr offset val = MkIO (\w =>  prim_io_return (+prim_poke8 ptr offset val = MkIO (\w =>  prim_io_pure (     prim__poke8 (world w) ptr offset val))  prim_peek16 : Ptr -> Int -> IO Bits16-prim_peek16 ptr offset = MkIO (\w => prim_io_return (prim__peek16 (world w) ptr offset))+prim_peek16 ptr offset = MkIO (\w => prim_io_pure (prim__peek16 (world w) ptr offset))  prim_poke16 : Ptr -> Int -> Bits16 -> IO Int-prim_poke16 ptr offset val = MkIO (\w =>  prim_io_return (+prim_poke16 ptr offset val = MkIO (\w =>  prim_io_pure (     prim__poke16 (world w) ptr offset val))  prim_peek32 : Ptr -> Int -> IO Bits32-prim_peek32 ptr offset = MkIO (\w => prim_io_return (prim__peek32 (world w) ptr offset))+prim_peek32 ptr offset = MkIO (\w => prim_io_pure (prim__peek32 (world w) ptr offset))  prim_poke32 : Ptr -> Int -> Bits32 -> IO Int-prim_poke32 ptr offset val = MkIO (\w =>  prim_io_return (+prim_poke32 ptr offset val = MkIO (\w =>  prim_io_pure (     prim__poke32 (world w) ptr offset val))  prim_peek64 : Ptr -> Int -> IO Bits64-prim_peek64 ptr offset = MkIO (\w => prim_io_return (prim__peek64 (world w) ptr offset))+prim_peek64 ptr offset = MkIO (\w => prim_io_pure (prim__peek64 (world w) ptr offset))  prim_poke64 : Ptr -> Int -> Bits64 -> IO Int-prim_poke64 ptr offset val = MkIO (\w =>  prim_io_return (+prim_poke64 ptr offset val = MkIO (\w =>  prim_io_pure (     prim__poke64 (world w) ptr offset val))  prim_peekPtr : Ptr -> Int -> IO Ptr-prim_peekPtr ptr offset = MkIO (\w => prim_io_return (prim__peekPtr (world w) ptr offset))+prim_peekPtr ptr offset = MkIO (\w => prim_io_pure (prim__peekPtr (world w) ptr offset))  prim_pokePtr : Ptr -> Int -> Ptr -> IO Int-prim_pokePtr ptr offset val = MkIO (\w =>  prim_io_return (+prim_pokePtr ptr offset val = MkIO (\w =>  prim_io_pure (     prim__pokePtr (world w) ptr offset val))  prim_peekDouble : Ptr -> Int -> IO Double-prim_peekDouble ptr offset = MkIO (\w => prim_io_return (prim__peekDouble (world w) ptr offset))+prim_peekDouble ptr offset = MkIO (\w => prim_io_pure (prim__peekDouble (world w) ptr offset))  prim_pokeDouble : Ptr -> Int -> Double -> IO Int-prim_pokeDouble ptr offset val = MkIO (\w =>  prim_io_return (+prim_pokeDouble ptr offset val = MkIO (\w =>  prim_io_pure (     prim__pokeDouble (world w) ptr offset val))  ||| Single precision floats are marshalled to Doubles prim_peekSingle : Ptr -> Int -> IO Double-prim_peekSingle ptr offset = MkIO (\w => prim_io_return (prim__peekSingle (world w) ptr offset))+prim_peekSingle ptr offset = MkIO (\w => prim_io_pure (prim__peekSingle (world w) ptr offset))  ||| Single precision floats are marshalled to Doubles prim_pokeSingle : Ptr -> Int -> Double -> IO Int-prim_pokeSingle ptr offset val = MkIO (\w =>  prim_io_return (+prim_pokeSingle ptr offset val = MkIO (\w =>  prim_io_pure (     prim__pokeSingle (world w) ptr offset val))
libs/prelude/Language/Reflection.idr view
@@ -65,15 +65,23 @@    data SpecialName = WhereN Int TTName TTName                    | WithN Int TTName-                   | InstanceN TTName (List String)+                   | ImplementationN TTName (List String)                    | ParentN TTName String                    | MethodN TTName                    | CaseN SourceLocation TTName                    | ElimN TTName-                   | InstanceCtorN TTName+                   | ImplementationCtorN TTName                    | MetaN TTName TTName   %name SpecialName sn, sn' +InstanceN : TTName -> (List String) -> SpecialName+InstanceN = ImplementationN+%deprecate InstanceN "`InstanceN` is deprecated, Please use `ImplementationN` instead."++InstanceCtorN : TTName ->  SpecialName+InstanceCtorN = ImplementationCtorN+%deprecate InstanceCtorN "`InstanceCtorN` is deprecated, Please use `ImplementationCtorN` instead."+ -- Rather  than  implement  one-off  private functions,  we  make  the -- disjointness of  the constructors available to  all Idris programs, -- at the cost of a bit of scrolling here.@@ -117,7 +125,7 @@ implementation Uninhabited ((WhereN x n n') = (WithN y z)) where   uninhabited Refl impossible -implementation Uninhabited ((WhereN x n n') = (InstanceN y xs)) where+implementation Uninhabited ((WhereN x n n') = (ImplementationN y xs)) where   uninhabited Refl impossible  implementation Uninhabited ((WhereN x n n') = (ParentN y z)) where@@ -132,7 +140,7 @@ implementation Uninhabited ((WhereN x n n') = (ElimN y)) where   uninhabited Refl impossible -implementation Uninhabited ((WhereN x n n') = (InstanceCtorN y)) where+implementation Uninhabited ((WhereN x n n') = (ImplementationCtorN y)) where   uninhabited Refl impossible  implementation Uninhabited ((WhereN x n n') = (MetaN y z)) where@@ -141,7 +149,7 @@ implementation Uninhabited ((WithN x n) = (WhereN y n' z)) where   uninhabited Refl impossible -implementation Uninhabited ((WithN x n) = (InstanceN n' xs)) where+implementation Uninhabited ((WithN x n) = (ImplementationN n' xs)) where   uninhabited Refl impossible  implementation Uninhabited ((WithN x n) = (ParentN n' y)) where@@ -156,34 +164,34 @@ implementation Uninhabited ((WithN x n) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((WithN x n) = (InstanceCtorN n')) where+implementation Uninhabited ((WithN x n) = (ImplementationCtorN n')) where   uninhabited Refl impossible  implementation Uninhabited ((WithN x n) = (MetaN n' y)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (WhereN x n' y)) where+implementation Uninhabited ((ImplementationN n xs) = (WhereN x n' y)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (WithN x n')) where+implementation Uninhabited ((ImplementationN n xs) = (WithN x n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (ParentN n' x)) where+implementation Uninhabited ((ImplementationN n xs) = (ParentN n' x)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (MethodN n')) where+implementation Uninhabited ((ImplementationN n xs) = (MethodN n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (CaseN loc n')) where+implementation Uninhabited ((ImplementationN n xs) = (CaseN loc n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (ElimN n')) where+implementation Uninhabited ((ImplementationN n xs) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (InstanceCtorN n')) where+implementation Uninhabited ((ImplementationN n xs) = (ImplementationCtorN n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceN n xs) = (MetaN n' x)) where+implementation Uninhabited ((ImplementationN n xs) = (MetaN n' x)) where   uninhabited Refl impossible  implementation Uninhabited ((ParentN n x) = (WhereN y n' z)) where@@ -192,7 +200,7 @@ implementation Uninhabited ((ParentN n x) = (WithN y n')) where   uninhabited Refl impossible -implementation Uninhabited ((ParentN n x) = (InstanceN n' xs)) where+implementation Uninhabited ((ParentN n x) = (ImplementationN n' xs)) where   uninhabited Refl impossible  implementation Uninhabited ((ParentN n x) = (MethodN n')) where@@ -204,7 +212,7 @@ implementation Uninhabited ((ParentN n x) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((ParentN n x) = (InstanceCtorN n')) where+implementation Uninhabited ((ParentN n x) = (ImplementationCtorN n')) where   uninhabited Refl impossible  implementation Uninhabited ((ParentN n x) = (MetaN n' y)) where@@ -216,7 +224,7 @@ implementation Uninhabited ((MethodN n) = (WithN x n')) where   uninhabited Refl impossible -implementation Uninhabited ((MethodN n) = (InstanceN n' xs)) where+implementation Uninhabited ((MethodN n) = (ImplementationN n' xs)) where   uninhabited Refl impossible  implementation Uninhabited ((MethodN n) = (ParentN n' x)) where@@ -228,7 +236,7 @@ implementation Uninhabited ((MethodN n) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((MethodN n) = (InstanceCtorN n')) where+implementation Uninhabited ((MethodN n) = (ImplementationCtorN n')) where   uninhabited Refl impossible  implementation Uninhabited ((MethodN n) = (MetaN n' x)) where@@ -240,7 +248,7 @@ implementation Uninhabited ((CaseN loc n) = (WithN x n')) where   uninhabited Refl impossible -implementation Uninhabited ((CaseN loc n) = (InstanceN n' xs)) where+implementation Uninhabited ((CaseN loc n) = (ImplementationN n' xs)) where   uninhabited Refl impossible  implementation Uninhabited ((CaseN loc n) = (ParentN n' x)) where@@ -252,7 +260,7 @@ implementation Uninhabited ((CaseN loc n) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((CaseN loc n) = (InstanceCtorN n')) where+implementation Uninhabited ((CaseN loc n) = (ImplementationCtorN n')) where   uninhabited Refl impossible  implementation Uninhabited ((CaseN loc n) = (MetaN n' x)) where@@ -264,7 +272,7 @@ implementation Uninhabited ((ElimN n) = (WithN x n')) where   uninhabited Refl impossible -implementation Uninhabited ((ElimN n) = (InstanceN n' xs)) where+implementation Uninhabited ((ElimN n) = (ImplementationN n' xs)) where   uninhabited Refl impossible  implementation Uninhabited ((ElimN n) = (ParentN n' x)) where@@ -276,34 +284,34 @@ implementation Uninhabited ((ElimN n) = (CaseN loc n')) where   uninhabited Refl impossible -implementation Uninhabited ((ElimN n) = (InstanceCtorN n')) where+implementation Uninhabited ((ElimN n) = (ImplementationCtorN n')) where   uninhabited Refl impossible  implementation Uninhabited ((ElimN n) = (MetaN n' x)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (WhereN x n' y)) where+implementation Uninhabited ((ImplementationCtorN n) = (WhereN x n' y)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (WithN x n')) where+implementation Uninhabited ((ImplementationCtorN n) = (WithN x n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (InstanceN n' xs)) where+implementation Uninhabited ((ImplementationCtorN n) = (ImplementationN n' xs)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (ParentN n' x)) where+implementation Uninhabited ((ImplementationCtorN n) = (ParentN n' x)) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (MethodN n')) where+implementation Uninhabited ((ImplementationCtorN n) = (MethodN n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (CaseN loc n')) where+implementation Uninhabited ((ImplementationCtorN n) = (CaseN loc n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (ElimN n')) where+implementation Uninhabited ((ImplementationCtorN n) = (ElimN n')) where   uninhabited Refl impossible -implementation Uninhabited ((InstanceCtorN n) = (MetaN n' x)) where+implementation Uninhabited ((ImplementationCtorN n) = (MetaN n' x)) where   uninhabited Refl impossible  implementation Uninhabited ((MetaN n n') = (WhereN x y z)) where@@ -312,7 +320,7 @@ implementation Uninhabited ((MetaN n n') = (WithN x y)) where   uninhabited Refl impossible -implementation Uninhabited ((MetaN n n') = (InstanceN x xs)) where+implementation Uninhabited ((MetaN n n') = (ImplementationN x xs)) where   uninhabited Refl impossible  implementation Uninhabited ((MetaN n n') = (ParentN x y)) where@@ -327,7 +335,7 @@ implementation Uninhabited ((MetaN n n') = (ElimN x)) where   uninhabited Refl impossible -implementation Uninhabited ((MetaN n n') = (InstanceCtorN x)) where+implementation Uninhabited ((MetaN n n') = (ImplementationCtorN x)) where   uninhabited Refl impossible  mutual@@ -396,10 +404,14 @@   withNInj Refl = (Refl, Refl)    private-  instanceNInj : (InstanceN n xs = InstanceN n' ys) -> (n = n', xs = ys)+  instanceNInj : (ImplementationN n xs = ImplementationN n' ys) -> (n = n', xs = ys)   instanceNInj Refl = (Refl, Refl)    private+  implementationNInj : (ImplementationN n xs = ImplementationN n' ys) -> (n = n', xs = ys)+  implementationNInj Refl = (Refl, Refl)+  +  private   parentNInj : (ParentN n x = ParentN n' y) -> (n = n', x = y)   parentNInj Refl = (Refl, Refl) @@ -416,8 +428,8 @@   elimNInj Refl = Refl    private-  instanceCtorNInj : (InstanceCtorN n = InstanceCtorN n') -> n = n'-  instanceCtorNInj Refl = Refl+  implementationCtorNInj : (ImplementationCtorN n = ImplementationCtorN n') -> n = n'+  implementationCtorNInj Refl = Refl    private   metaNInj : (MetaN n m = MetaN n' m') -> (n = n', m = m')@@ -437,12 +449,12 @@     decSNEq (WhereN x n n') (WhereN y z w) | No contra =         No $ contra . fst . whereNInj   decSNEq (WhereN x n n') (WithN y z) = No absurd-  decSNEq (WhereN x n n') (InstanceN y xs) = No absurd+  decSNEq (WhereN x n n') (ImplementationN y xs) = No absurd   decSNEq (WhereN x n n') (ParentN y z) = No absurd   decSNEq (WhereN x n n') (MethodN y) = No absurd   decSNEq (WhereN x n n') (CaseN loc y) = No absurd   decSNEq (WhereN x n n') (ElimN y) = No absurd-  decSNEq (WhereN x n n') (InstanceCtorN y) = No absurd+  decSNEq (WhereN x n n') (ImplementationCtorN y) = No absurd   decSNEq (WhereN x n n') (MetaN y z) = No absurd   decSNEq (WithN x n) (WhereN y n' z) = No absurd   decSNEq (WithN x n) (WithN y n') with (decEq x y)@@ -453,32 +465,32 @@           No $ contra . snd . withNInj     decSNEq (WithN x n) (WithN y n') | No contra =         No $ contra . fst . withNInj-  decSNEq (WithN x n) (InstanceN n' xs) = No absurd+  decSNEq (WithN x n) (ImplementationN n' xs) = No absurd   decSNEq (WithN x n) (ParentN n' y) = No absurd   decSNEq (WithN x n) (MethodN n') = No absurd   decSNEq (WithN x n) (CaseN loc n') = No absurd   decSNEq (WithN x n) (ElimN n') = No absurd-  decSNEq (WithN x n) (InstanceCtorN n') = No absurd+  decSNEq (WithN x n) (ImplementationCtorN n') = No absurd   decSNEq (WithN x n) (MetaN n' y) = No absurd-  decSNEq (InstanceN n xs) (WhereN x n' y) = No absurd-  decSNEq (InstanceN n xs) (WithN x n') = No absurd-  decSNEq (InstanceN n xs) (InstanceN n' ys) with (assert_total $ decTTNameEq n n')-    decSNEq (InstanceN n xs) (InstanceN n ys)  | Yes Refl with (decEq xs ys)-      decSNEq (InstanceN n xs) (InstanceN n xs)  | Yes Refl | Yes Refl =+  decSNEq (ImplementationN n xs) (WhereN x n' y) = No absurd+  decSNEq (ImplementationN n xs) (WithN x n') = No absurd+  decSNEq (ImplementationN n xs) (ImplementationN n' ys) with (assert_total $ decTTNameEq n n')+    decSNEq (ImplementationN n xs) (ImplementationN n ys)  | Yes Refl with (decEq xs ys)+      decSNEq (ImplementationN n xs) (ImplementationN n xs)  | Yes Refl | Yes Refl =           Yes Refl-      decSNEq (InstanceN n xs) (InstanceN n ys)  | Yes Refl | No contra =-          No $ contra . snd . instanceNInj-    decSNEq (InstanceN n xs) (InstanceN n' ys) | No contra =-        No $ contra . fst . instanceNInj-  decSNEq (InstanceN n xs) (ParentN n' x) = No absurd-  decSNEq (InstanceN n xs) (MethodN n') = No absurd-  decSNEq (InstanceN n xs) (CaseN loc n') = No absurd-  decSNEq (InstanceN n xs) (ElimN n') = No absurd-  decSNEq (InstanceN n xs) (InstanceCtorN n') = No absurd-  decSNEq (InstanceN n xs) (MetaN n' x) = No absurd+      decSNEq (ImplementationN n xs) (ImplementationN n ys)  | Yes Refl | No contra =+          No $ contra . snd . implementationNInj+    decSNEq (ImplementationN n xs) (ImplementationN n' ys) | No contra =+        No $ contra . fst . implementationNInj+  decSNEq (ImplementationN n xs) (ParentN n' x) = No absurd+  decSNEq (ImplementationN n xs) (MethodN n') = No absurd+  decSNEq (ImplementationN n xs) (CaseN loc n') = No absurd+  decSNEq (ImplementationN n xs) (ElimN n') = No absurd+  decSNEq (ImplementationN n xs) (ImplementationCtorN n') = No absurd+  decSNEq (ImplementationN n xs) (MetaN n' x) = No absurd   decSNEq (ParentN n x) (WhereN y n' z) = No absurd   decSNEq (ParentN n x) (WithN y n') = No absurd-  decSNEq (ParentN n x) (InstanceN n' xs) = No absurd+  decSNEq (ParentN n x) (ImplementationN n' xs) = No absurd   decSNEq (ParentN n x) (ParentN n' y) with (assert_total $ decTTNameEq n n')     decSNEq (ParentN n x) (ParentN n y)  | Yes Refl with (decEq x y)       decSNEq (ParentN n x) (ParentN n x) | Yes Refl | Yes Refl =@@ -490,11 +502,11 @@   decSNEq (ParentN n x) (MethodN n') = No absurd   decSNEq (ParentN n x) (CaseN loc n') = No absurd   decSNEq (ParentN n x) (ElimN n') = No absurd-  decSNEq (ParentN n x) (InstanceCtorN n') = No absurd+  decSNEq (ParentN n x) (ImplementationCtorN n') = No absurd   decSNEq (ParentN n x) (MetaN n' y) = No absurd   decSNEq (MethodN n) (WhereN x n' y) = No absurd   decSNEq (MethodN n) (WithN x n') = No absurd-  decSNEq (MethodN n) (InstanceN n' xs) = No absurd+  decSNEq (MethodN n) (ImplementationN n' xs) = No absurd   decSNEq (MethodN n) (ParentN n' x) = No absurd   decSNEq (MethodN n) (MethodN n') with (assert_total $ decTTNameEq n n')     decSNEq (MethodN n) (MethodN n)  | Yes Refl =@@ -503,11 +515,11 @@         No $ contra . methodNInj   decSNEq (MethodN n) (CaseN loc n') = No absurd   decSNEq (MethodN n) (ElimN n') = No absurd-  decSNEq (MethodN n) (InstanceCtorN n') = No absurd+  decSNEq (MethodN n) (ImplementationCtorN n') = No absurd   decSNEq (MethodN n) (MetaN n' x) = No absurd   decSNEq (CaseN loc n) (WhereN x n' y) = No absurd   decSNEq (CaseN loc n) (WithN x n') = No absurd-  decSNEq (CaseN loc n) (InstanceN n' xs) = No absurd+  decSNEq (CaseN loc n) (ImplementationN n' xs) = No absurd   decSNEq (CaseN loc n) (ParentN n' x) = No absurd   decSNEq (CaseN loc n) (MethodN n') = No absurd   decSNEq (CaseN loc n) (CaseN loc' n') with (decEq loc loc')@@ -519,11 +531,11 @@     decSNEq (CaseN loc n) (CaseN loc' n') | No contra =         No $ contra . fst . caseNInj   decSNEq (CaseN loc n) (ElimN n') = No absurd-  decSNEq (CaseN loc n) (InstanceCtorN n') = No absurd+  decSNEq (CaseN loc n) (ImplementationCtorN n') = No absurd   decSNEq (CaseN loc n) (MetaN n' x) = No absurd   decSNEq (ElimN n) (WhereN x n' y) = No absurd   decSNEq (ElimN n) (WithN x n') = No absurd-  decSNEq (ElimN n) (InstanceN n' xs) = No absurd+  decSNEq (ElimN n) (ImplementationN n' xs) = No absurd   decSNEq (ElimN n) (ParentN n' x) = No absurd   decSNEq (ElimN n) (MethodN n') = No absurd   decSNEq (ElimN n) (CaseN loc n') = No absurd@@ -532,29 +544,29 @@         Yes Refl     decSNEq (ElimN n) (ElimN n') | No contra =         No $ contra . elimNInj-  decSNEq (ElimN n) (InstanceCtorN n') = No absurd+  decSNEq (ElimN n) (ImplementationCtorN n') = No absurd   decSNEq (ElimN n) (MetaN n' x) = No absurd-  decSNEq (InstanceCtorN n) (WhereN x n' y) = No absurd-  decSNEq (InstanceCtorN n) (WithN x n') = No absurd-  decSNEq (InstanceCtorN n) (InstanceN n' xs) = No absurd-  decSNEq (InstanceCtorN n) (ParentN n' x) = No absurd-  decSNEq (InstanceCtorN n) (MethodN n') = No absurd-  decSNEq (InstanceCtorN n) (CaseN loc n') = No absurd-  decSNEq (InstanceCtorN n) (ElimN n') = No absurd-  decSNEq (InstanceCtorN n) (InstanceCtorN n') with (assert_total $ decTTNameEq n n')-    decSNEq (InstanceCtorN n) (InstanceCtorN n)  | Yes Refl =+  decSNEq (ImplementationCtorN n) (WhereN x n' y) = No absurd+  decSNEq (ImplementationCtorN n) (WithN x n') = No absurd+  decSNEq (ImplementationCtorN n) (ImplementationN n' xs) = No absurd+  decSNEq (ImplementationCtorN n) (ParentN n' x) = No absurd+  decSNEq (ImplementationCtorN n) (MethodN n') = No absurd+  decSNEq (ImplementationCtorN n) (CaseN loc n') = No absurd+  decSNEq (ImplementationCtorN n) (ElimN n') = No absurd+  decSNEq (ImplementationCtorN n) (ImplementationCtorN n') with (assert_total $ decTTNameEq n n')+    decSNEq (ImplementationCtorN n) (ImplementationCtorN n)  | Yes Refl =         Yes Refl-    decSNEq (InstanceCtorN n) (InstanceCtorN n') | No contra =-        No $ contra . instanceCtorNInj-  decSNEq (InstanceCtorN n) (MetaN n' x) = No absurd+    decSNEq (ImplementationCtorN n) (ImplementationCtorN n') | No contra =+        No $ contra . implementationCtorNInj+  decSNEq (ImplementationCtorN n) (MetaN n' x) = No absurd   decSNEq (MetaN n n') (WhereN x y z) = No absurd   decSNEq (MetaN n n') (WithN x y) = No absurd-  decSNEq (MetaN n n') (InstanceN x xs) = No absurd+  decSNEq (MetaN n n') (ImplementationN x xs) = No absurd   decSNEq (MetaN n n') (ParentN x y) = No absurd   decSNEq (MetaN n n') (MethodN x) = No absurd   decSNEq (MetaN n n') (CaseN loc x) = No absurd   decSNEq (MetaN n n') (ElimN x) = No absurd-  decSNEq (MetaN n n') (InstanceCtorN x) = No absurd+  decSNEq (MetaN n n') (ImplementationCtorN x) = No absurd   decSNEq (MetaN n n') (MetaN x y) with (assert_total $ decTTNameEq n x)     decSNEq (MetaN n n') (MetaN n y) | Yes Refl with (assert_total $ decTTNameEq n' y)       decSNEq (MetaN n n') (MetaN n n') | Yes Refl | Yes Refl =@@ -564,6 +576,9 @@     decSNEq (MetaN n n') (MetaN x y) | No contra =         No $ contra . fst . metaNInj +-- (Temporarily?) Outside the mutual block, since otherwise we get the+-- warning on the second pass!+%deprecate instanceNInj "`instanceNInj` is deprecated, Please use `implementationNInj` instead."  implementation DecEq TTName where   decEq = decTTNameEq@@ -798,7 +813,7 @@             ||| Build a proof by applying contructors up to a maximum depth             Search Int |             ||| Resolve an interface-            Instance |+            Implementation |             ||| Infer the proof target from the context             Solve |             ||| introduce all variables into the context@@ -995,12 +1010,12 @@     quotedTy = `(SpecialName)     quote (WhereN i n1 n2) = `(WhereN ~(quote i) ~(quote n1) ~(quote n2))     quote (WithN i n) = `(WithN ~(quote i) ~(quote n))-    quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))+    quote (ImplementationN i ss) = `(ImplementationN ~(quote i) ~(quote ss))     quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))     quote (MethodN n) = `(MethodN ~(quote n))     quote (CaseN fc n) = `(CaseN ~(quote fc) ~(quote n))     quote (ElimN n) = `(ElimN ~(quote n))-    quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))+    quote (ImplementationCtorN n) = `(ImplementationCtorN ~(quote n))     quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))  mutual@@ -1015,12 +1030,12 @@     quotedTy = `(SpecialName)     quote (WhereN i n1 n2) = `(WhereN ~(quote i) ~(quote n1) ~(quote n2))     quote (WithN i n) = `(WithN ~(quote i) ~(quote n))-    quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))+    quote (ImplementationN i ss) = `(ImplementationN ~(quote i) ~(quote ss))     quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))     quote (MethodN n) = `(MethodN ~(quote n))     quote (CaseN fc n) = `(CaseN ~(quote fc) ~(quote n))     quote (ElimN n) = `(ElimN ~(quote n))-    quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))+    quote (ImplementationCtorN n) = `(ImplementationCtorN ~(quote n))     quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))  @@ -1272,7 +1287,7 @@   quote (Seq tac tac') = `(Seq ~(quote tac) ~(quote tac'))   quote Trivial = `(Trivial)   quote (Search x) = `(Search ~(quote x))-  quote Instance = `(Instance)+  quote Implementation = `(Implementation)   quote Solve = `(Solve)   quote Intros = `(Intros)   quote (Intro n) = `(Intro ~(quote n))@@ -1302,7 +1317,7 @@   quote (Seq tac tac') = `(Seq ~(quote tac) ~(quote tac'))   quote Trivial = `(Trivial)   quote (Search x) = `(Search ~(quote x))-  quote Instance = `(Instance)+  quote Implementation = `(Implementation)   quote Solve = `(Solve)   quote Intros = `(Intros)   quote (Intro n) = `(Intro ~(quote n))
libs/prelude/Language/Reflection/Elab.idr view
@@ -182,7 +182,7 @@   Prim__DefineFunction : FunDefn Raw -> Elab ()   Prim__DeclareDatatype : TyDecl -> Elab ()   Prim__DefineDatatype : DataDefn -> Elab ()-  Prim__AddInstance : TTName -> TTName -> Elab ()+  Prim__AddImplementation : TTName -> TTName -> Elab ()   Prim__IsTCName : TTName -> Elab Bool    Prim__ResolveTC : TTName -> Elab ()@@ -253,7 +253,7 @@   export   lookupTyExact : TTName -> Elab (TTName, NameType, TT)   lookupTyExact n = case !(lookupTy n) of-                      [res] => return res+                      [res] => pure res                       []    => fail [NamePart n, TextPart "is not defined."]                       xs    => fail [NamePart n, TextPart "is ambiguous."] @@ -269,7 +269,7 @@   export   lookupDatatypeExact : TTName -> Elab Datatype   lookupDatatypeExact n = case !(lookupDatatype n) of-                            [res] => return res+                            [res] => pure res                             []    => fail [TextPart "No datatype named", NamePart n]                             xs    => fail [TextPart "More than one datatype named", NamePart n] @@ -285,7 +285,7 @@   export   lookupFunDefnExact : TTName -> Elab (FunDefn TT)   lookupFunDefnExact n = case !(lookupFunDefn n) of-                           [res] => return res+                           [res] => pure res                            []    => fail [TextPart "No function named", NamePart n]                            xs    => fail [TextPart "More than one function named", NamePart n] @@ -299,7 +299,7 @@   export   lookupArgsExact : TTName -> Elab (TTName, List FunArg, Raw)   lookupArgsExact n = case !(lookupArgs n) of-                        [res] => return res+                        [res] => pure res                         []    => fail [NamePart n, TextPart "is not defined."]                         xs    => fail [NamePart n, TextPart "is ambiguous."] @@ -555,10 +555,15 @@   ||| Register a new implementation for interface resolution.   |||   ||| @ ifaceName the name of the interface for which an implementation is being registered-  ||| @ instName the name of the definition to use in implementation search+  ||| @ implName the name of the definition to use in implementation search   export-  addInstance : (ifaceName, instName : TTName) -> Elab ()-  addInstance ifaceName instName = Prim__AddInstance ifaceName instName+  addImplementation : (ifaceName, implName : TTName) -> Elab ()+  addImplementation ifaceName implName = Prim__AddImplementation ifaceName implName++  export+  addInstance : (ifaceName, implName : TTName) -> Elab ()+  addInstance = addImplementation+  %deprecate addInstance "`addInstance` is deprecated, Please use `addImplementation` instead."    ||| Determine whether a name denotes an interface.   |||
libs/prelude/Prelude.idr view
@@ -50,7 +50,7 @@ ---- Functor implementations  Functor PrimIO where-    map f io = prim_io_bind io (prim_io_return . f)+    map f io = prim_io_bind io (prim_io_pure . f)  Functor Maybe where     map f (Just x) = Just (f x)@@ -63,9 +63,9 @@ ---- Applicative implementations  Applicative PrimIO where-    pure = prim_io_return+    pure = prim_io_pure -    am <*> bm = prim_io_bind am (\f => prim_io_bind bm (prim_io_return . f))+    am <*> bm = prim_io_bind am (\f => prim_io_bind bm (prim_io_pure . f))  Applicative Maybe where     pure = Just@@ -252,19 +252,19 @@   partial   nullPtr : Ptr -> JS_IO Bool   nullPtr p = do ok <- foreign FFI_JS "isNull" (Ptr -> JS_IO Int) p-                 return (ok /= 0)+                 pure (ok /= 0)    ||| Check if a supposed string was actually a null pointer   partial   nullStr : String -> JS_IO Bool   nullStr p = do ok <- foreign FFI_JS "isNull" (String -> JS_IO Int) p-                 return (ok /= 0)+                 pure (ok /= 0)   ||| Pointer equality eqPtr : Ptr -> Ptr -> IO Bool eqPtr x y = do eq <- foreign FFI_C "idris_eqPtr" (Ptr -> Ptr -> IO Int) x y-               return (eq /= 0)+               pure (eq /= 0)  ||| Loop while some test is true |||@@ -275,7 +275,7 @@ while t b = do v <- t                if v then do b                             while t b-                    else return ()+                    else pure ()  ------- Some error rewriting 
libs/prelude/Prelude/Either.idr view
@@ -89,7 +89,7 @@   ----------------------------------------------------------------------------------- Instances+-- Implementations --------------------------------------------------------------------------------  (Eq a, Eq b) => Eq (Either a b) where
libs/prelude/Prelude/File.idr view
@@ -40,9 +40,10 @@                   (foreign FFI_C "idris_showerror" (Int -> IO String) err)  getFileError : IO FileError-getFileError = do MkRaw err <- foreign FFI_C "idris_mkFileError"-                                    (Ptr -> IO (Raw FileError)) prim__vm-                  return err+getFileError = do vm <- getMyVM+                  MkRaw err <- foreign FFI_C "idris_mkFileError"+                                    (Ptr -> IO (Raw FileError)) vm+                  pure err  Show FileError where   show FileReadError = "File Read Error"@@ -73,7 +74,7 @@ export ferror : File -> IO Bool ferror (FHandle h) = do err <- do_ferror h-                        return (not (err == 0))+                        pure (not (err == 0))  ||| Call the RTS's file opening function private@@ -89,14 +90,14 @@ fopen f m = do h <- do_fopen f m                if !(nullPtr h)                   then do err <- getFileError-                          return (Left err)-                  else return (Right (FHandle h))+                          pure (Left err)+                  else pure (Right (FHandle h))  ||| Check whether a file handle is actually a null pointer export validFile : File -> IO Bool validFile (FHandle h) = do x <- nullPtr h-                           return (not x)+                           pure (not x)  ||| Modes for opening files data Mode = Read | WriteTruncate | Append | ReadWrite | ReadWriteTruncate | ReadAppend@@ -148,8 +149,8 @@ fileSize (FHandle h) = do s <- do_getFileSize h                           if (s < 0)                               then do err <- getFileError-                                     return (Left err)-                             else return (Right s) +                                     pure (Left err)+                             else pure (Right s)  private do_fread : Ptr -> IO' l String@@ -159,8 +160,8 @@ fgetc : File -> IO (Either FileError Char) fgetc (FHandle h) = do let c = cast !(foreign FFI_C "fgetc" (Ptr -> IO Int) h)                        if !(ferror (FHandle h))-                          then return (Left FileReadError)-                          else return (Right c)+                          then pure (Left FileReadError)+                          else pure (Right c)  export fflush : File -> IO ()@@ -175,8 +176,8 @@ popen f m = do ptr <- do_popen f (modeStr m)                if !(nullPtr ptr)                   then do err <- getFileError-                          return (Left err)-                  else return (Right (FHandle ptr))+                          pure (Left err)+                  else pure (Right (FHandle ptr))  export pclose : File -> IO ()@@ -189,8 +190,8 @@ fread : File -> IO (Either FileError String) fread (FHandle h) = do str <- do_fread h                        if !(ferror (FHandle h))-                          then return (Left FileReadError)-                          else return (Right str)+                          then pure (Left FileReadError)+                          else pure (Right str)  ||| Read a line from a file ||| @h a file handle which must be open for reading@@ -206,10 +207,10 @@                    if (res /= 0)                       then do errno <- getErrno                               if errno == 0-                                 then return (Left FileWriteError)+                                 then pure (Left FileWriteError)                                  else do err <- getFileError-                                         return (Left err)-                      else return (Right ())+                                         pure (Left err)+                      else pure (Right ())  export fwrite : File -> String -> IO (Either FileError ())@@ -236,7 +237,7 @@ export fEOF : File -> IO Bool fEOF (FHandle h) = do eof <- do_feof h-                      return (not (eof == 0))+                      pure (not (eof == 0))  ||| Check if a file handle has reached the end export@@ -248,7 +249,7 @@ export fpoll : File -> IO Bool fpoll (FHandle h) = do p <- foreign FFI_C "fpoll" (Ptr -> IO Int) h-                       return (p > 0)+                       pure (p > 0)  ||| Read the contents of a file into a string ||| This checks the size of the file before beginning to read, and only@@ -258,29 +259,29 @@ export readFile : (filepath : String) -> IO (Either FileError String) readFile fn = do Right h <- openFile fn Read-                    | Left err => return (Left err)+                    | Left err => pure (Left err)                  Right max <- fileSize h-                    | Left err => return (Left err)+                    | Left err => pure (Left err)                  c <- readFile' h max ""                  closeFile h-                 return c+                 pure c   where     readFile' : File -> Int -> String -> IO (Either FileError String)     readFile' h max contents =        do x <- fEOF h           if not x && max > 0                    then do Right l <- fGetLine h-                               | Left err => return (Left err)+                               | Left err => pure (Left err)                            assert_total $                              readFile' h (max - cast (length l)) (contents ++ l)-                   else return (Right contents)+                   else pure (Right contents)  ||| Write a string to a file export writeFile : (filepath : String) -> (contents : String) ->             IO (Either FileError ()) writeFile fn contents = do-     Right h  <- openFile fn WriteTruncate | Left err => return (Left err)-     Right () <- fPutStr h contents        | Left err => return (Left err)+     Right h  <- openFile fn WriteTruncate | Left err => pure (Left err)+     Right () <- fPutStr h contents        | Left err => pure (Left err)      closeFile h-     return (Right ())+     pure (Right ())
libs/prelude/Prelude/Foldable.idr view
@@ -16,7 +16,7 @@ ||| @t The type of the 'Foldable' parameterised type. interface Foldable (t : Type -> Type) where -  ||| Successivly combine the elements in a parameterised type using+  ||| Successively combine the elements in a parameterised type using   ||| the provided function, starting with the element that is in the   ||| final position i.e. the right-most position.   |||
libs/prelude/Prelude/Interactive.idr view
@@ -29,7 +29,7 @@ ||| descriptor putStr' : String -> IO' ffi () putStr' x = do prim_write x-               return ()+               pure ()  ||| Output a string to stdout without a trailing newline putStr : String -> IO ()@@ -66,7 +66,7 @@ ||| descriptor getLine' : IO' ffi String getLine' = do x <- prim_read-              return (reverse (trimNL (reverse x)))+              pure (reverse (trimNL (reverse x)))   where trimNL : String -> String         trimNL str with (strM str)           trimNL "" | StrNil = ""@@ -103,7 +103,7 @@      partial     ga' : List String -> Int -> Int -> IO (List String)-    ga' acc i n = if (i == n) then (return $ reverse acc) else+    ga' acc i n = if (i == n) then (pure $ reverse acc) else                     do arg <- getArg i                        ga' (arg :: acc) (i+1) n @@ -155,7 +155,7 @@         case fn acc x of              Just (out, acc') => do putStr out                                     replWith acc' prompt fn-             Nothing => return ()+             Nothing => pure ()  ||| A basic read-eval-print loop ||| @ prompt the prompt to show
libs/prelude/Prelude/Interfaces.idr view
@@ -354,11 +354,11 @@ -- ------------------------------------------------------------------- [ Bits8 ] divB8 : Bits8 -> Bits8 -> Bits8 divB8 x y = case y == 0 of-  False => prim__sdivB8 x y+  False => prim__udivB8 x y  modB8 : Bits8 -> Bits8 -> Bits8 modB8 x y = case y == 0 of-  False => prim__sremB8 x y+  False => prim__uremB8 x y  Integral Bits8 where   div = divB8@@ -367,11 +367,11 @@ -- ------------------------------------------------------------------ [ Bits16 ] divB16 : Bits16 -> Bits16 -> Bits16 divB16 x y = case y == 0 of-  False => prim__sdivB16 x y+  False => prim__udivB16 x y  modB16 : Bits16 -> Bits16 -> Bits16 modB16 x y = case y == 0 of-  False => prim__sremB16 x y+  False => prim__uremB16 x y  Integral Bits16 where   div = divB16@@ -380,11 +380,11 @@ -- ------------------------------------------------------------------ [ Bits32 ] divB32 : Bits32 -> Bits32 -> Bits32 divB32 x y = case y == 0 of-  False => prim__sdivB32 x y+  False => prim__udivB32 x y  modB32 : Bits32 -> Bits32 -> Bits32 modB32 x y = case y == 0 of-  False => prim__sremB32 x y+  False => prim__uremB32 x y  Integral Bits32 where   div = divB32@@ -393,11 +393,11 @@ -- ------------------------------------------------------------------ [ Bits64 ] divB64 : Bits64 -> Bits64 -> Bits64 divB64 x y = case y == 0 of-  False => prim__sdivB64 x y+  False => prim__udivB64 x y  modB64 : Bits64 -> Bits64 -> Bits64 modB64 x y = case y == 0 of-  False => prim__sremB64 x y+  False => prim__uremB64 x y  Integral Bits64 where   div = divB64
libs/prelude/Prelude/List.idr view
@@ -249,7 +249,7 @@ replicate (S n) x = x :: replicate n x  ----------------------------------------------------------------------------------- Instances+-- Implementations --------------------------------------------------------------------------------  (Eq a) => Eq (List a) where@@ -363,6 +363,32 @@ ||| Convert any Foldable structure to a list. toList : Foldable t => t a -> List a toList = foldr (::) []++--------------------------------------------------------------------------------+-- Scans+--------------------------------------------------------------------------------++||| The scanl function is similar to foldl, but returns all the intermediate+||| accumulator states in the form of a list.+|||+|||````idris example+|||scanl (+) 0 [1,2,3,4]+|||````+scanl : (b -> a -> b) -> b -> List a -> List b+scanl f q []      = [q]+scanl f q (x::xs) = q :: scanl f (f q x) xs++||| The scanl1 function is a variant of scanl that doesn't require an explicit +||| starting value.+||| It assumes the first element of the list to be the starting value and then+||| starts the fold with the element following it.+|||+|||````idris example+|||scanl1 (+) [1,2,3,4]+|||````+scanl1 : (a -> a -> a) -> List a -> List a+scanl1 _ []      = []+scanl1 f (x::xs) = scanl f x xs  -------------------------------------------------------------------------------- -- Transformations
libs/prelude/Prelude/Monad.idr view
@@ -4,7 +4,7 @@  import Builtins import Prelude.Functor-import Prelude.Applicative+import public Prelude.Applicative import Prelude.Basics import IO @@ -27,6 +27,7 @@ ||| define `return` and `pure` differently! return : Monad m => a -> m a return = pure+%deprecate return "Please use `pure`, which is equivalent."  flatten : Monad m => m (m a) -> m a flatten = join@@ -36,13 +37,13 @@ -- Prelude modules other than the top level.  Functor (IO' ffi) where-    map f io = io_bind io (\b => io_return (f b))+    map f io = io_bind io (\b => io_pure (f b))  Applicative (IO' ffi) where-    pure x = io_return x+    pure x = io_pure x     f <*> a = io_bind f (\f' =>                 io_bind a (\a' =>-                  io_return (f' a')))+                  io_pure (f' a')))   Monad (IO' ffi) where
libs/prelude/Prelude/Nat.idr view
@@ -197,7 +197,7 @@ (-) m n {smaller} = minus m n  ----------------------------------------------------------------------------------- Type class implementations+-- Interface implementations --------------------------------------------------------------------------------  Eq Nat where
libs/prelude/Prelude/Pairs.idr view
@@ -49,5 +49,5 @@     getProof = snd     %deprecate DPair.getProof "This is being deprecated in favour of `snd`." -  -- Polymorphic (class-based) projections have been removed+  -- Polymorphic (interface-based) projections have been removed   -- because type-directed name disambiguation works better.
libs/prelude/Prelude/Strings.idr view
@@ -247,10 +247,11 @@ ||| lines' (unpack "\rA BC\nD\r\nE\n") ||| ``` lines' : List Char -> List (List Char)-lines' s = case dropWhile isNL s of-            [] => []-            s' => let (w, s'') = break isNL s'-                  in w :: lines' (assert_smaller s s'')+lines' [] = []+lines' s  = case break isNL s of+              (l, s') => l :: case s' of+                                []       => []+                                _ :: s'' => lines' (assert_smaller s s'')  ||| Splits a string into a list of newline separated strings. |||@@ -286,9 +287,7 @@ ||| ``` unlines' : List (List Char) -> List Char unlines' [] = []-unlines' ls = assert_total (foldr1 addLine ls) where-  addLine : List Char -> List Char -> List Char-  addLine l s = l ++ ('\n' :: s)+unlines' (l::ls) = l ++ '\n' :: unlines' ls  ||| Joins the strings by newlines into a single string. |||@@ -359,10 +358,10 @@ partial nullPtr : Ptr -> IO Bool nullPtr p = do ok <- foreign FFI_C "isNull" (Ptr -> IO Int) p-               return (ok /= 0)+               pure (ok /= 0)  ||| Check if a supposed string was actually a null pointer partial nullStr : String -> IO Bool nullStr p = do ok <- foreign FFI_C "isNull" (String -> IO Int) p-               return (ok /= 0)+               pure (ok /= 0)
libs/pruviloj/Pruviloj/Core.idr view
@@ -87,7 +87,7 @@ newHole hint ty =     do hn <- gensym hint        claim hn ty-       return hn+       pure hn  ||| Use a term to solve a hole |||@@ -105,7 +105,7 @@             do n' <- nameFrom n                intro n'                (n' ::) <$> go body-        go _ = return []+        go _ = pure []  ||| Run a tactic inside of a particular hole, if it still exists. If ||| it has been solved, do nothing.@@ -113,7 +113,7 @@ inHole h todo =   if (h `elem` !getHoles)     then do focus h; Just <$> todo-    else return Nothing+    else pure Nothing  ||| Restrict a polymorphic type to () for contexts where it doesn't ||| matter. This is nice for sticking `debug` in a context where@@ -132,7 +132,7 @@        claim h newGoal        fill (Var h); solve        focus h-       return h+       pure h  ||| Remember a term built with elaboration for later use. If the ||| current goal is `h`, then `remember n ty` puts a fresh hole at@@ -149,14 +149,14 @@        claim todo ty        letbind n ty (Var todo)        focus todo-       return todo+       pure todo  ||| Repeat a given tactic until it fails. Fails if the tactic fails on ||| the first attempt; succeeds otherwise. repeatUntilFail : Elab () -> Elab () repeatUntilFail tac =     do tac-       repeatUntilFail tac <|> return ()+       repeatUntilFail tac <|> pure ()  ||| If the current goal is a pattern-bound variable, bind it with the ||| expected name. Otherwise fail.@@ -181,7 +181,7 @@ inferType : (tac : Elab ()) -> Elab (TT, TT) inferType tac =     case fst !(runElab `(Infer) (do startInfer; tac)) of-        `(MkInfer ~ty ~tm) => return (tm, ty)+        `(MkInfer ~ty ~tm) => pure (tm, ty)         _ => fail [TextPart "Not infer"]   where     startInfer : Elab ()@@ -219,7 +219,7 @@        newHoles <- apply tm (replicate argCount True)        solve        actualHoles <- getHoles-       return (filter (flip elem actualHoles) newHoles)+       pure (filter (flip elem actualHoles) newHoles)    where countPi : Raw -> Nat         countPi (RBind _ (Pi _ _) body) = S (countPi body)
libs/pruviloj/Pruviloj/Derive/DecEq.idr view
@@ -116,7 +116,7 @@                                       focus a1; fill rTm1; solve                                       focus a2; fill rTm2; solve                                       focus dH; resolveTC fn-                          return (Var eq)+                          pure (Var eq)                      matchCase tms       _ => fail [TextPart "Inapplicable"] @@ -127,7 +127,7 @@ ||| deriving to occur. It must consist of zero or more non-constraint ||| arguments followed by zero or more constraint arguments, followed ||| by the two values to compare. The constraint arguments must-||| provide sufficient instances of `DecEq` to decide the equality of+||| provide sufficient implementations of `DecEq` to decide the equality of ||| each constructor field. The final two arguments to the function ||| declaration must be the two values that will be compared for ||| equality.@@ -165,7 +165,7 @@              (a2 :: a1 :: rest) =>                do (constrs, bindings) <- partitionM (\x => isConstr (binderTy (snd x)))                                                     (reverse rest)-                  return (bindings, constrs, a1, a2)+                  pure (bindings, constrs, a1, a2)        let todo = [(c1, c2) | c1 <- constructors datatype                             , c2 <- constructors datatype]        clauses <- for todo@@ -178,7 +178,7 @@     isConstr : Raw -> Elab Bool     isConstr tm = case headName tm of                     Just n => isTCName n-                    Nothing => return False+                    Nothing => pure False      partial -- mkRhs     mkCase : Nat -> TTName -> (x, y : (TTName, List CtorArg, Raw)) -> Elab (Maybe (FunClause Raw))
libs/pruviloj/Pruviloj/Derive/Eliminators.idr view
@@ -20,7 +20,7 @@ bindIndices : TyConInfo -> Elab Renamer bindIndices info = bind' (getIndices info) noRenames   where bind' : List (TTName, Raw) -> Renamer -> Elab Renamer-        bind' []              ren = return ren+        bind' []              ren = pure ren         bind' ((n, t) :: ixs) ren = do n' <- nameFrom n                                        forall n' (alphaRaw ren t)                                        bind' ixs (extend ren n n')@@ -31,7 +31,7 @@ bindTarget info = do ren <- bindIndices info                      tn <- gensym "target"                      forall tn (alphaRaw ren $ result info)-                     return (tn, ren)+                     pure (tn, ren)  elabMotive : TyConInfo -> Elab () elabMotive info = do attack@@ -75,7 +75,7 @@                 fill argTm; solve                 solve -- attack                 solve -- ihT-        else return ()+        else pure ()  elabMethodTy : TyConInfo -> TTName -> List CtorArg -> Raw -> Raw -> Elab () elabMethodTy info motiveName [] res ctorApp =@@ -146,7 +146,7 @@         -- Establish a hole for each argument to the constructor         for {b=()} args $ \arg =>           case arg of-            CtorParameter _ => return ()+            CtorParameter _ => pure ()             CtorField arg => do claim (name arg) (type arg)                                 unfocus (name arg) @@ -187,16 +187,16 @@                      for args                          (\x =>                             case x of-                              CtorParameter _ => return List.Nil+                              CtorParameter _ => pure List.Nil                               CtorField arg =>                                 do let n = name arg                                    let t = type arg                                    (argArgs, argRes) <- stealBindings t noRenames                                    if headsMatch argRes (result info) --recursive-                                     then return [ NormalArgument n-                                                 , IHArgument n-                                                 ]-                                     else return [NormalArgument n])+                                     then pure [ NormalArgument n+                                               , IHArgument n+                                               ]+                                     else pure [NormalArgument n])          argHs <- apply (Var methN) (replicate (List.length argSpec) True)         solve@@ -261,5 +261,5 @@      clauses <- getElimClauses info elimn ctors       defineFunction $ DefineFun elimn clauses-     return ()+     pure () 
libs/pruviloj/Pruviloj/Disjoint.idr view
@@ -30,7 +30,7 @@    where exists : Elab TTName         exists = do (yep, _, _) <- lookupTyExact (disjointName l r)-                    return yep+                    pure yep          notConstructor : TTName -> Elab a         notConstructor c = fail [NamePart c, TextPart "is not a constructor"]@@ -58,7 +58,7 @@                      h <- gensym "h"                      declareType $ Declare fn (args ++ [MkFunArg h eq Explicit NotErased]) `(Void)                      defineFunction $ DefineFun fn []-                     return fn+                     pure fn  ---------------------- -- PUBLIC INTERFACE --
libs/pruviloj/Pruviloj/Induction.idr view
@@ -63,12 +63,12 @@  generalize : (hint : String) -> (ctxt, subject : Raw) -> Elab (TTName, Raw) generalize hint ctxt subj = do n <- gensym hint-                               return (n, !(gen' n ctxt subj))+                               pure (n, !(gen' n ctxt subj))   where     mutual       gen' : TTName -> Raw -> Raw -> Elab Raw       gen' var outer inner = if alphaEqual (const Nothing) outer inner-                               then return (Var var)+                               then pure (Var var)                                else breakAndRecurse var outer inner        genB : TTName -> Binder Raw -> Raw -> Elab (Binder Raw)@@ -87,10 +87,10 @@           do n' <- nameFrom n              b' <- genB var b inner              body' <- gen' var (alphaRaw (rename n n') tm) inner-             return $ RBind n' b' body'+             pure $ RBind n' b' body'       breakAndRecurse var (RApp tm tm') inner =           [| RApp (gen' var tm inner) (gen' var tm' inner) |]-      breakAndRecurse var other inner = return other+      breakAndRecurse var other inner = pure other   countBinders : TT -> Nat@@ -105,7 +105,7 @@      let argsTogether = zip tyArgs (args info)      (argVal, TyConIndex _) <- argsTogether              | _ => empty-     return argVal+     pure argVal  makeMotive : (info : TyConInfo) -> (subj, subjTy, goal : Raw) -> Elab () makeMotive info sub subjTy goal =@@ -154,4 +154,4 @@               motiveH <- unsafeNth (length (args info) + 1) argHoles               focus motiveH; makeMotive info subj ty' g -              return (drop (2 + length (tyConArgs tydef)) argHoles)+              pure (drop (2 + length (tyConArgs tydef)) argHoles)
libs/pruviloj/Pruviloj/Injective.idr view
@@ -27,7 +27,7 @@   where exists : Elab TTName         exists = do (fn, Ref, _) <- lookupTyExact (injName cn)                       | (fn, _, _) => fail [TextPart "Bad earlier declaration of", NamePart fn]-                    return fn+                    pure fn          covering         declare : Elab TTName@@ -73,7 +73,7 @@                                  search -- rhs is conjunction of Refls                      defineFunction $                        DefineFun fn [clause]-                     return fn+                     pure fn  countBinders : TT -> Nat countBinders (Bind _ _ body) = S (countBinders body)
libs/pruviloj/Pruviloj/Internals.idr view
@@ -33,13 +33,13 @@ stealBindings (RBind n b tm) nsubst =   do n' <- nameFrom n      (bindings, result) <- stealBindings tm (extend nsubst n n')-     return ((n', map (alphaRaw nsubst) b) :: bindings, result)-stealBindings tm nsubst = return ([], alphaRaw nsubst tm)+     pure ((n', map (alphaRaw nsubst) b) :: bindings, result)+stealBindings tm nsubst = pure ([], alphaRaw nsubst tm)  ||| Get the last element of a list. Fail on empty lists. last : List a -> Elab a last [] = fail [TextPart "Unexpected empty list"]-last [x] = return x+last [x] = pure x last (_::x::xs) = last (x::xs)  ||| Grab the binders from around a term, assuming that they have been@@ -110,10 +110,10 @@         | fail [TextPart "Couldn't infer type of left-hand pattern"]      rhsTm <- runElab (bindPatTys pvars rhsTy) $                 do -- Introduce all the pattern variables from the LHS-                   repeatUntilFail bindPat <|> return ()+                   repeatUntilFail bindPat <|> pure ()                    rhs      realRhs <- forget (fst rhsTm)-     return $ MkFunClause (bindPats pvars lhsTm) realRhs+     pure $ MkFunClause (bindPats pvars lhsTm) realRhs  ||| Introduce a unique binder name, returning it intro1 : Elab TTName@@ -121,7 +121,7 @@             case g of               Bind n (Pi _ _) _ => do n' <- nameFrom n                                       intro n'-                                      return n'+                                      pure n'               _ => fail [ TextPart "Can't intro1 because goal"                         , TermPart g                         , TextPart "isn't a function type."]@@ -134,13 +134,13 @@  ||| Zip two lists, failing if their lengths don't match. zipH : List a -> List b -> Elab (List (a, b))-zipH [] [] = return []+zipH [] [] = pure [] zipH (x::xs) (y::ys) = ((x, y) ::) <$> zipH xs ys zipH _ _ = fail [TextPart "length mismatch"]  unsafeNth : Nat -> List a -> Elab a unsafeNth _     []        = fail [TextPart "Ran out of list elements"]-unsafeNth Z     (x :: _)  = return x+unsafeNth Z     (x :: _)  = pure x unsafeNth (S k) (_ :: xs) = unsafeNth k xs  
libs/pruviloj/Pruviloj/Internals/TyConInfo.idr view
@@ -51,14 +51,14 @@   in MkTyConInfo (tcArg'::tcArgs') res'  getTyConInfo' : List TyConArg -> Raw -> (TTName -> Maybe TTName) -> Elab TyConInfo-getTyConInfo' [] res _ = return (MkTyConInfo [] res)+getTyConInfo' [] res _ = pure (MkTyConInfo [] res) getTyConInfo' (tcArg::tcArgs) res ren =   do let n = tyConArgName tcArg      n' <- nameFrom n      let ren' = extend ren n n'      -- n' is globally unique so we don't worry about scope      next <- getTyConInfo' tcArgs (RApp res (Var n')) ren'-     return $ alphaTyConInfo ren' $+     pure $ alphaTyConInfo ren' $        record {args = setTyConArgName tcArg n' :: args next} next  getTyConInfo : List TyConArg -> Raw -> Elab TyConInfo@@ -68,14 +68,14 @@ processCtorArgs : TyConInfo -> (TTName, List CtorArg, Raw) -> Elab (TTName, List CtorArg, Raw) processCtorArgs info (cn, cargs, resTy) =     do (args', ty') <- convert' (const Nothing) cargs resTy info-       return (cn, args', ty')+       pure (cn, args', ty')   where     ||| Find the name that was assigned to a given parameter     ||| by comparing positions in the TyConInfo     findParam : TTName -> List Raw -> List TyConArg -> Elab TTName     findParam paramN (Var n :: args) (TyConParameter a :: tcArgs) =       if n == paramN-        then return (name a)+        then pure (name a)         else findParam paramN args tcArgs     findParam paramN (_ :: args) (_ :: tcArgs) =       findParam paramN args tcArgs@@ -87,7 +87,7 @@     convert' : (TTName -> Maybe TTName) ->                List CtorArg -> Raw ->                TyConInfo -> Elab (List CtorArg, Raw)-    convert' subst [] ty info = return ([], alphaRaw subst ty)+    convert' subst [] ty info = pure ([], alphaRaw subst ty)     convert' subst (CtorField a :: args) ty info =       do n' <- nameFrom (name a)          let a' = record {@@ -96,7 +96,7 @@                   } a          let subst' = extend subst (name a) n'          (args', ty') <- convert' subst' args ty info-         return (CtorField a' :: args', ty')+         pure (CtorField a' :: args', ty')     convert' subst (CtorParameter a :: ctorArgs) ty info =       do n' <- findParam (name a) (snd (unApply ty)) (args info)          let a' = record {@@ -105,4 +105,4 @@                   } a          let subst' = extend subst (name a) n'          (args', ty') <- convert' subst' ctorArgs ty info-         return (CtorParameter a' :: args', ty')+         pure (CtorParameter a' :: args', ty')
+ libs/pruviloj/README.txt view
@@ -0,0 +1,45 @@+  ___                   _+ /   \               _ / \      _+|  |  |             / \| |     / \+|  |  | _  _ _  _ _ \_/| | ___ \_/+| ---/ \ \/ \ \/ \ \/ \| |/   \/ \+| |  |  -/| | || | || || || | || |+| |  | |  | | |\ | /| || || | || |+\_/  \_/  \___/ \_/ \_/\_/\___/| |+                              _/ |+                             |__/+     a proof automation and program construction toolkit+++Pruviloj is a library of tactics that work with Idris's elaborator+reflection. In addition to a library of small tactics, it contains+code for generating eliminators for inductive datatypes and using+those eliminators to do induction.+++Q: How do I use Pruviloj?+A: Call Idris with the "-p pruviloj" option and add:+      import Pruviloj+   to the top of your file. If you want to do induction, then+   add:+      import Pruviloj.Induction+   as well.+++Q: How do I find out what's available?+A: Use ":browse Pruviloj.Core" after importing the library.+   Pruviloj.Induction exports only one name: "induction".+   Use ":doc" to read the built-in documentation.+++Q: How do I use the tactics?+A: Please read the Idris documentation on elaborator reflection.+   The syntax to invoke a tactic script is "%runElab script". To+   interactively work with a hole, use ":elab holeName".+++Q: Where does the name come from?+A: "Pruviloj" is Esperanto for "proof tools". The stress goes on+   the penultimate syllable, and in IPA the pronunciation is written+   [pruˈvi.loi̯]. Perhaps confusingly for Esperantists, the Pruviloj+   library also contains utilities for code generation.
+ logos/logo-text.svg view
@@ -0,0 +1,150 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with VectorDraw -->++<svg+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="595.000000"+   height="841.000000"+   id="svg2"+   version="1.1"+   inkscape:version="0.91 r13725"+   sodipodi:docname="logo3-text.svg"+   inkscape:export-filename="/Users/edwin/Idris/Logos/logo3-text.png"+   inkscape:export-xdpi="90"+   inkscape:export-ydpi="90">+  <metadata+     id="metadata11">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <defs+     id="defs9">+    <linearGradient+       id="linearGradient5872"+       osb:paint="solid">+      <stop+         style="stop-color:#000000;stop-opacity:1;"+         offset="0"+         id="stop5874" />+    </linearGradient>+    <inkscape:perspective+       sodipodi:type="inkscape:persp3d"+       inkscape:vp_x="0 : 420.5 : 1"+       inkscape:vp_y="0 : 1000 : 0"+       inkscape:vp_z="595 : 420.5 : 1"+       inkscape:persp3d-origin="297.5 : 280.33333 : 1"+       id="perspective3611" />+    <filter+       style="color-interpolation-filters:sRGB;"+       inkscape:label="Drop Shadow"+       id="filter5878">+      <feFlood+         flood-opacity="0.498039"+         flood-color="rgb(0,0,0)"+         result="flood"+         id="feFlood5880" />+      <feComposite+         in="flood"+         in2="SourceGraphic"+         operator="in"+         result="composite1"+         id="feComposite5882" />+      <feGaussianBlur+         in="composite1"+         stdDeviation="3"+         result="blur"+         id="feGaussianBlur5884" />+      <feOffset+         dx="6"+         dy="6"+         result="offset"+         id="feOffset5886" />+      <feComposite+         in="SourceGraphic"+         in2="offset"+         operator="over"+         result="composite2"+         id="feComposite5888" />+    </filter>+  </defs>+  <sodipodi:namedview+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1"+     objecttolerance="10"+     gridtolerance="10"+     guidetolerance="10"+     inkscape:pageopacity="0"+     inkscape:pageshadow="2"+     inkscape:window-width="1408"+     inkscape:window-height="845"+     id="namedview7"+     showgrid="false"+     inkscape:zoom="2.2991361"+     inkscape:cx="215.71271"+     inkscape:cy="745.84286"+     inkscape:window-x="14"+     inkscape:window-y="0"+     inkscape:window-maximized="0"+     inkscape:current-layer="" />+  <g+     inkscape:label=""+     inkscape:groupmode="layer"+     id="">+    <g+       id="g3353"+       transform="matrix(0.32905346,0,0,0.32905346,7.0998413,0.25431021)"+       style="image-rendering:auto;fill:#aa0000;stroke:none;stroke-opacity:1;filter:url(#filter5878)"+       inkscape:export-xdpi="35.079365"+       inkscape:export-ydpi="35.079365">+      <path+         inkscape:connector-curvature="0"+         id="path3345"+         d="M 79.07716,85.235105 C 152.15731,107.3516 170.85211,125.57188 196.54561,191.60466 191.5621,111.08837 159.33816,77.523083 79.07716,85.235105 c 18.82716,-67.890093 0,0 0,0 z"+         style="fill:#aa0000;fill-opacity:1;stroke:none;stroke-opacity:1" />+      <path+         inkscape:connector-curvature="0"+         id="path3343"+         d="M -22.207669,211.87449 C 25.234912,226.48437 80.323859,238.15903 100.68023,328.79942 109.08411,215.72166 55.546121,209.96088 -22.207669,211.87449 c 90.648682,-302.180016 0,0 0,0 z"+         style="fill:#aa0000;fill-opacity:1;stroke:none;stroke-opacity:1" />+      <path+         inkscape:connector-curvature="0"+         id="path3341"+         d="M 9.8483347,139.76992 C 81.136615,154.50235 126.58014,173.85823 153.14004,265.85432 159.23348,147.17442 94.093917,135.25771 9.8483347,139.76992 c 78.3893863,-131.1880199 0,0 0,0 z"+         style="fill:#aa0000;fill-opacity:1;stroke:none;stroke-opacity:1" />+      <path+         id="path5"+         d="M 103.33025,0.379032 C 492.35181,254.04105 16.917801,258.5227 120.33008,553.01685 c 0,0 61.21588,17.8269 61.21588,17.8269 C 12.902722,342.22024 556.89801,224.698 103.33025,0.379032 c 0,0 0,0 0,0 z"+         style="fill:#aa0000;fill-opacity:1;stroke:none;stroke-opacity:1"+         inkscape:connector-curvature="0" />+    </g>+    <text+       xml:space="preserve"+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:173.13887024px;line-height:125%;font-family:'TeX Gyre Pagella';-inkscape-font-specification:'TeX Gyre Pagella, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"+       x="123.74978"+       y="186.47948"+       id="text3569"+       sodipodi:linespacing="125%"+       transform="scale(1.0060826,0.99395418)"+       inkscape:export-xdpi="35.079365"+       inkscape:export-ydpi="35.079365"><tspan+         sodipodi:role="line"+         id="tspan3571"+         x="123.74978"+         y="186.47948">Idris</tspan></text>+  </g>+</svg>
+ logos/logo.svg view
@@ -0,0 +1,80 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with VectorDraw -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="595.000000"+   height="841.000000"+   id="svg2"+   version="1.1"+   inkscape:version="0.91 r13725"+   sodipodi:docname="logo2.svg">+  <metadata+     id="metadata11">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <defs+     id="defs9" />+  <sodipodi:namedview+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1"+     objecttolerance="10"+     gridtolerance="10"+     guidetolerance="10"+     inkscape:pageopacity="0"+     inkscape:pageshadow="2"+     inkscape:window-width="1198"+     inkscape:window-height="1598"+     id="namedview7"+     showgrid="false"+     inkscape:zoom="0.56123662"+     inkscape:cx="52.74404"+     inkscape:cy="241.68009"+     inkscape:window-x="1280"+     inkscape:window-y="0"+     inkscape:window-maximized="0"+     inkscape:current-layer="" />+  <g+     inkscape:label=""+     inkscape:groupmode="layer"+     id="">+    <g+       id="g3353"+       transform="translate(22,0)">+      <path+         inkscape:connector-curvature="0"+         id="path3345"+         d="M 79.07716,85.235105 C 152.15731,107.3516 170.85211,125.57188 196.54561,191.60466 191.5621,111.08837 159.33816,77.523083 79.07716,85.235105 c 18.82716,-67.890093 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         inkscape:connector-curvature="0"+         id="path3343"+         d="M -22.207669,211.87449 C 25.234912,226.48437 80.323859,238.15903 100.68023,328.79942 109.08411,215.72166 55.546121,209.96088 -22.207669,211.87449 c 90.648682,-302.180016 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         inkscape:connector-curvature="0"+         id="path3341"+         d="M 9.8483347,139.76992 C 81.136615,154.50235 126.58014,173.85823 153.14004,265.85432 159.23348,147.17442 94.093917,135.25771 9.8483347,139.76992 c 78.3893863,-131.1880199 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none" />+      <path+         id="path5"+         d="M 103.33025,0.379032 C 492.35181,254.04105 16.917801,258.5227 120.33008,553.01685 c 0,0 61.21588,17.8269 61.21588,17.8269 C 12.902722,342.22024 556.89801,224.698 103.33025,0.379032 c 0,0 0,0 0,0 z"+         style="fill:#8a0819;fill-opacity:1;stroke:none"+         inkscape:connector-curvature="0" />+    </g>+  </g>+</svg>
main/Main.hs view
@@ -1,91 +1,72 @@ module Main where -import System.Exit ( exitSuccess )- import Control.Monad ( when )+import System.Exit ( exitSuccess )  import Idris.AbsSyntax-import Idris.REPL-import Idris.Imports import Idris.Error import Idris.CmdOptions-+import Idris.Info+import Idris.Info.Show import Idris.Package--import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )+import Idris.Main  import Util.System ( setupBundledCC ) +processShowOptions :: [Opt] -> Idris ()+processShowOptions opts = runIO $ do+  when (ShowAll `elem` opts)          $ showExitIdrisInfo+  when (ShowLoggingCats `elem` opts)  $ showExitIdrisLoggingCategories+  when (ShowIncs `elem` opts)         $ showExitIdrisFlagsInc+  when (ShowLibs `elem` opts)         $ showExitIdrisFlagsLibs+  when (ShowLibdir `elem` opts)       $ showExitIdrisLibDir+  when (ShowPkgs `elem` opts)         $ showExitIdrisInstalledPackages +check :: [Opt] -> (Opt -> Maybe a) -> ([a] -> Idris ()) -> Idris ()+check opts extractOpts action = do+  case opt extractOpts opts of+    [] -> return ()+    fs -> do action fs+             runIO exitSuccess --- Main program reads command line options, parses the main program, and gets--- on with the REPL.+processClientOptions :: [Opt] -> Idris ()+processClientOptions opts = check opts getClient $ \fs -> case fs of+  (c:_) -> do+    setVerbose False+    setQuiet True+    case getPort opts of+      Just  DontListen       -> ifail "\"--client\" and \"--port none\" are incompatible"+      Just (ListenPort port) -> runIO $ runClient (Just port) c+      Nothing                -> runIO $ runClient Nothing c -main :: IO ()-main = do opts <- runArgParser-          runMain (runIdris opts)+processPackageOptions :: [Opt] -> Idris ()+processPackageOptions opts = do+  check opts getPkgCheck $ \fs -> runIO $ do+    mapM_ (checkPkg opts (WarnOnly `elem` opts) True) fs+  check opts getPkgClean $ \fs -> runIO $ do+    mapM_ (cleanPkg opts) fs+  check opts getPkgMkDoc $ \fs -> runIO $ do+    mapM_ (documentPkg opts) fs+  check opts getPkgTest $ \fs -> runIO $ do+    mapM_ (testPkg opts) fs+  check opts getPkg $ \fs -> runIO $ do+    mapM_ (buildPkg opts (WarnOnly `elem` opts)) fs+  check opts getPkgREPL $ \fs -> case fs of+    [f] -> replPkg opts f+    _   -> ifail "Too many packages" +-- | The main function for the Idris executable. runIdris :: [Opt] -> Idris () runIdris opts = do-    runIO setupBundledCC-    when (ShowLoggingCats `elem` opts)  $ runIO showLoggingCats-    when (ShowIncs `elem` opts)         $ runIO showIncs-    when (ShowLibs `elem` opts)         $ runIO showLibs-    when (ShowLibdir `elem` opts)       $ runIO showLibdir-    when (ShowPkgs `elem` opts)         $ runIO showPkgs-    case opt getClient opts of-       []    -> return ()-       (c:_) -> do setVerbose False-                   setQuiet True-                   runIO $ runClient (getPort opts) c-                   runIO exitSuccess-    case opt getPkgCheck opts of-       [] -> return ()-       fs -> do runIO $ mapM_ (checkPkg opts (WarnOnly `elem` opts) True) fs-                runIO exitSuccess-    case opt getPkgClean opts of-       [] -> return ()-       fs -> do runIO $ mapM_ (cleanPkg opts) fs-                runIO exitSuccess-    case opt getPkgMkDoc opts of                -- IdrisDoc-       [] -> return ()-       fs -> do runIO $ mapM_ (documentPkg opts) fs-                runIO exitSuccess-    case opt getPkgTest opts of-       [] -> return ()-       fs -> do runIO $ mapM_ (testPkg opts) fs-                runIO exitSuccess-    case opt getPkg opts of-       [] -> case opt getPkgREPL opts of-                  [] -> idrisMain opts-                  [f] -> replPkg opts f-                  _ -> ifail "Too many packages"-       fs -> runIO $ mapM_ (buildPkg opts (WarnOnly `elem` opts)) fs--showver :: IO b-showver = do putStrLn $ "Idris version " ++ ver-             exitSuccess--showLibs :: IO b-showLibs = do libFlags <- getLibFlags-              putStrLn $ unwords libFlags-              exitSuccess--showLibdir :: IO b-showLibdir = do putStrLn =<< getIdrisLibDir-                exitSuccess--showIncs :: IO b-showIncs = do incFlags <- getIncFlags-              putStrLn $ unwords incFlags-              exitSuccess---- | List idris packages installed-showPkgs :: IO b-showPkgs = do mapM_ putStrLn =<< installedPackages-              exitSuccess+  runIO setupBundledCC+  processShowOptions opts    -- Show information then quit.+  processClientOptions opts  -- Be a client to a REPL server.+  processPackageOptions opts -- Work with Idris packages.+  idrisMain opts             -- Launch REPL or compile mode. -showLoggingCats :: IO b-showLoggingCats = do-    putStrLn loggingCatsStr-    exitSuccess+-- Main program reads command line options, parses the main program, and gets+-- on with the REPL.+main :: IO ()+main = do+  opts <- runArgParser+  runMain (runIdris opts)
man/idris.1 view
@@ -1,6 +1,6 @@ .\" Manpage for Idris. .\" Contact <> to correct errors or typos.-.TH man 1 "25 March 2016" "0.12.2" "Idris man page"+.TH man 1 "25 March 2016" "0.12.3" "Idris man page" .SH NAME idris -\ a general purpose pure functional programming language with dependent types. .SH SYNOPSIS@@ -59,6 +59,7 @@   -V,--verbose             Loud verbosity   --ibcsubdir FILE         Write IBC files into sub directory   -i,--idrispath ARG       Add directory to the list of import paths+  --sourcepath ARG         Add directory to the list of source search paths   -p,--package ARG         Add package as a dependency   --port PORT              REPL TCP port   --build IPKG             Build package
+ mkpkg.sh view
@@ -0,0 +1,26 @@+#!/bin/sh++VERSION=$1++echo "Building version-$VERSION\n\n"+echo "Have you: set the release flag, checked the demos and the tutorial?"+read $foo++git tag v$VERSION -a++cabal sdist++# Generate Idris library docs and put them in lib_docs.tar.gz in the root+make lib_doc+DOCDIR=`mktemp -d /tmp/docsXXXXX`+cp -r libs/base/base_doc "$DOCDIR"+cp -r libs/prelude/prelude_doc "$DOCDIR"+cp -r libs/effects/effects_doc "$DOCDIR"+cp -r libs/contrib/contrib_doc "$DOCDIR"+tar -czvf lib_docs.tar.gz -C "$DOCDIR" prelude_doc base_doc effects_doc contrib_doc++cabal configure --prefix=/usr/local+cabal build+cabal copy --destdir=/tmp/idris-pkg/+pkgbuild --id org.idris-lang --root /tmp/idris-pkg/ idris-$VERSION.pkg +
rts/idris_gmp.c view
@@ -23,20 +23,25 @@ }  VAL MKBIGC(VM* vm, char* val) {-    idris_requireAlloc(IDRIS_MAXGMP);-    mpz_t* bigint;-    -    VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);-    idris_doneAlloc();-    bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));-    -    mpz_init(*bigint);-    mpz_set_str(*bigint, val, 10);+    if (*val == '\0') {+        return MKBIGI(0);+    }+    else {+        idris_requireAlloc(IDRIS_MAXGMP);+        mpz_t* bigint;+        +        VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);+        idris_doneAlloc();+        bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));+        +        mpz_init(*bigint);+        mpz_set_str(*bigint, val, 10); -    SETTY(cl, CT_BIGINT);-    cl -> info.ptr = (void*)bigint;+        SETTY(cl, CT_BIGINT);+        cl -> info.ptr = (void*)bigint; -    return cl;+        return cl;+    } }  VAL MKBIGM(VM* vm, void* big) {
rts/idris_rts.h view
@@ -213,7 +213,7 @@  typedef intptr_t i_int; -#define MKINT(x) ((void*)((x)<<1)+1)+#define MKINT(x) ((void*)((i_int)(((x)<<1)+1))) #define GETINT(x) ((i_int)(x)>>1) #define ISINT(x) ((((i_int)x)&1) == 1) #define ISSTR(x) (GETTY(x) == CT_STRING)
samples/effects/Exception.idr view
@@ -7,7 +7,7 @@  data MyErr = NotANumber | OutOfRange -instance Show MyErr where+implementation Show MyErr where     show NotANumber = "Not a number"     show OutOfRange = "Out of range" 
+ samples/effects/Makefile view
@@ -0,0 +1,8 @@+check:+	rm -f *.ibc+	for x in *.idr ; do \+	echo "Checking $$x"; \+	idris -p effects --check $$x; \+	done++.PHONY: check
samples/effects/TreeTag.idr view
@@ -6,7 +6,7 @@ data BTree a = Leaf              | Node (BTree a) a (BTree a) -instance Show a => Show (BTree a) where+implementation Show a => Show (BTree a) where   show Leaf = "[]"   show (Node l x r) = "[" ++ show l ++ " "                           ++ show x ++ " "
+ samples/misc/Makefile view
@@ -0,0 +1,8 @@+check:+	rm -f *.ibc+	for x in *.idr ; do \+	echo "Checking $$x"; \+	idris --check $$x; \+	done++.PHONY: check
samples/misc/binary.idr view
@@ -4,7 +4,7 @@      b0 : Bit 0      b1 : Bit 1 -instance Show (Bit n) where+implementation Show (Bit n) where      show b0 = "0"      show b1 = "1" @@ -14,7 +14,7 @@      zero : Binary Z Z      (#)  : Binary w v -> Bit bit -> Binary (S w) (bit + 2 * v) -instance Show (Binary w k) where+implementation Show (Binary w k) where      show zero = ""      show (bin # bit) = show bin ++ show bit 
samples/misc/interp.idr view
@@ -51,7 +51,7 @@   (<) : Expr G TyInt -> Expr G TyInt -> Expr G TyBool   (<) = Op (<) -  instance Num (Expr G TyInt) where+  implementation Num (Expr G TyInt) where     (+) x y = Op (+) x y     (-) x y = Op (-) x y     (*) x y = Op (*) x y
+ samples/misc/named_implementation.lidr view
@@ -0,0 +1,36 @@+> module MyOrd++An alternative Ord implementation for Nats, with an explicit name "myord"+for the dictionary:++> implementation [myord] Ord Nat where+>    compare O (S n)     = GT+>    compare (S n) O     = LT+>    compare O O         = EQ++The @{name} syntax below gives an explicit dictionary for the compare function.+Here, we're telling it to use the "myord" dictionary. Otherwise, it'd just+use the default (unnamed) implementation. Note that there can only be one unnamed+implementation --- they must not overlap.++>    compare (S x) (S y) = compare @{myord} x y++> foo : List Nat+> foo = [1,4,2,8,3,7,5,6]++Sort foo using the default comparison operator:++> test1 : List Nat+> test1 = sort foo++-- which gives [1,2,3,4,5,6,7,8]++Sort foo using the alternative implementation. No need for 'sortBy' and other+such functions. Hoorah!++> test2 : List Nat+> test2 = sort @{myord} foo++-- which gives [8,7,6,5,4,3,2,1]++
− samples/misc/named_instance.lidr
@@ -1,36 +0,0 @@-> module MyOrd--An alternative Ord instance for Nats, with an explicit name "myord"-for the dictionary:--> instance [myord] Ord Nat where->    compare O (S n)     = GT->    compare (S n) O     = LT->    compare O O         = EQ--The @{name} syntax below gives an explicit dictionary for the compare function.-Here, we're telling it to use the "myord" dictionary. Otherwise, it'd just-use the default (unnamed) instance. Note that there can only be one unnamed-instance --- they must not overlap.-->    compare (S x) (S y) = compare @{myord} x y--> foo : List Nat-> foo = [1,4,2,8,3,7,5,6]--Sort foo using the default comparison operator:--> test1 : List Nat-> test1 = sort foo---- which gives [1,2,3,4,5,6,7,8]--Sort foo using the alternative instance. No need for 'sortBy' and other-such functions. Hoorah!--> test2 : List Nat-> test2 = sort @{myord} foo---- which gives [8,7,6,5,4,3,2,1]--
+ samples/tutorial/Makefile view
@@ -0,0 +1,11 @@+check: .PHONY+	rm -f *.ibc+	for x in *.idr ; do \+	echo "Checking $$x"; \+	idris --check $$x; \+	done++clean:+	rm -f *.ibc++.PHONY:
samples/tutorial/binary.idr view
@@ -5,7 +5,7 @@     bO : Binary n -> Binary (n + n)     bI : Binary n -> Binary (S (n + n)) -instance Show (Binary n) where+implementation Show (Binary n) where     show (bO x) = show x ++ "0"     show (bI x) = show x ++ "1"     show bEnd = ""
samples/tutorial/idiom.idr view
@@ -13,10 +13,10 @@     fetchVal [] = Nothing     fetchVal ((v, val) :: xs) = if (x == v) then (Just val) else (fetchVal xs) -instance Functor Eval where+implementation Functor Eval where     map f (MkEval g) = MkEval (\e => map f (g e)) -instance Applicative Eval where+implementation Applicative Eval where     pure x = MkEval (\e => Just x)      (<*>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where
+ scripts/generate-multi-ghc-travis-template view
@@ -0,0 +1,20 @@+#!/usr/bin/env bash++set -eu++script=$(basename "$0")++if [[ ! -r idris.cabal ]]; then+  echo "$script: Execute this script in the idris root directory" >&2+  exit 2+fi++if [[ ! -r ../multi-ghc-travis/make_travis_yml.hs ]]; then+  echo "$script: Expected to find multi-ghc-travis at ../multi-ghc-travis"+  exit 2+fi++output=travis-template.yml+../multi-ghc-travis/make_travis_yml.hs idris.cabal cppcheck hscolour >${output}++echo Now compare the generated ${output} with .travis.yml
+ src/.ghci view
@@ -0,0 +1,2 @@+:set -XMultiParamTypeClasses -XFunctionalDependencies+:set -XFlexibleInstances -XTemplateHaskell
src/IRTS/CodegenC.hs view
@@ -340,6 +340,7 @@       = indent i ++         c_irts (toFType rty) (creg l ++ " = ")                    (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"+bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined." bcc i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed bcc i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n" -- bcc i c = error (show c) -- indent i ++ "// not done yet\n"@@ -627,11 +628,11 @@        = v ++ "MKINT((i_int)(idris_writeStr(GETPTR(" ++ creg x                               ++ "),GETSTR("                               ++ creg s ++ "))))"-doOp v (LExternal vm) [] | vm == sUN "prim__vm" = v ++ "MKPTR(vm, vm)" doOp v (LExternal si) [] | si == sUN "prim__stdin" = v ++ "MKPTR(vm, stdin)" doOp v (LExternal so) [] | so == sUN "prim__stdout" = v ++ "MKPTR(vm, stdout)" doOp v (LExternal se) [] | se == sUN "prim__stderr" = v ++ "MKPTR(vm, stderr)" +doOp v (LExternal vm) [_] | vm == sUN "prim__vm" = v ++ "MKPTR(vm, vm)" doOp v (LExternal nul) [] | nul == sUN "prim__null" = v ++ "MKPTR(vm, NULL)" doOp v (LExternal eqp) [x, y] | eqp == sUN "prim__eqPtr"     = v ++ "MKINT((i_int)(GETPTR(" ++ creg x ++ ") == GETPTR(" ++ creg y ++ ")))"
src/IRTS/Compiler.hs view
@@ -185,12 +185,12 @@      snRank :: SpecialName -> String     snRank (WhereN i n n') = "1" ++ nameRank n' ++ nameRank n ++ show i-    snRank (InstanceN n args) = "2" ++ nameRank n ++ concatMap show args+    snRank (ImplementationN n args) = "2" ++ nameRank n ++ concatMap show args     snRank (ParentN n s) = "3" ++ nameRank n ++ show s     snRank (MethodN n) = "4" ++ nameRank n     snRank (CaseN _ n) = "5" ++ nameRank n     snRank (ElimN n) = "6" ++ nameRank n-    snRank (InstanceCtorN n) = "7" ++ nameRank n+    snRank (ImplementationCtorN n) = "7" ++ nameRank n     snRank (WithN i n) = "8" ++ nameRank n ++ show i  isCon (TyDecl _ _) = True@@ -628,12 +628,12 @@     LConCase (-1) n usedArgs <$> irSC top (methodVars `M.union` vs) sc   where     methodVars = case n of-        SN (InstanceCtorN className)+        SN (ImplementationCtorN interfaceName)             -> M.fromList [(v, VI                 { viMethod = Just $ mkFieldName n i                 }) | (v,i) <- zip args [0..]]         _-            -> M.empty -- not an instance constructor+            -> M.empty -- not an implementation constructor  irAlt top vs _ (ConstCase x rhs)     | matchable   x = LConstCase x <$> irSC top vs rhs
src/IRTS/System.hs view
@@ -32,8 +32,13 @@ #endif  overrideDataDirWith :: String -> IO FilePath-overrideDataDirWith envVar = do envValue <- lookupEnv envVar-                                maybe getDataDir return envValue+overrideDataDirWith envVar = do+  envValue <- lookupEnv envVar+  case envValue of+    Nothing -> do+      ddir <- getDataDir+      return (ddir </> "libs")+    Just ddir -> return ddir  getCC :: IO String getCC = fromMaybe "gcc" <$> lookupEnv "IDRIS_CC"
src/Idris/ASTUtils.hs view
@@ -40,7 +40,7 @@ module Idris.ASTUtils(     Field(), cg_usedpos, ctxt_lookup, fgetState, fmodifyState   , fputState, idris_fixities, ist_callgraph, ist_optimisation-  , known_classes, known_terms, opt_detaggable, opt_inaccessible+  , known_interfaces, known_terms, opt_detaggable, opt_inaccessible   , opts_idrisCmdline, repl_definitions   ) where @@ -148,8 +148,8 @@ known_terms = Field (definitions . tt_ctxt)                     (\v state -> state {tt_ctxt = (tt_ctxt state) {definitions = v}}) -known_classes :: Field IState (Ctxt ClassInfo)-known_classes = Field idris_classes (\v state -> state {idris_classes = idris_classes state})+known_interfaces :: Field IState (Ctxt InterfaceInfo)+known_interfaces = Field idris_interfaces (\v state -> state {idris_interfaces = idris_interfaces state})   -- | Names defined at the repl
src/Idris/AbsSyntax.hs view
@@ -47,6 +47,8 @@  import System.IO.Error(isUserError, ioeGetErrorString, tryIOError) +import Network (PortID(PortNumber))+ import Util.Pretty import Util.ScreenSize import Util.System@@ -422,9 +424,9 @@   return $ lookupCtxtExact n (idris_fragile i)  push_estack :: Name -> Bool -> Idris ()-push_estack n inst+push_estack n impl     = do i <- getIState-         putIState (i { elab_stack = (n, inst) : elab_stack i })+         putIState (i { elab_stack = (n, impl) : elab_stack i })  pop_estack :: Idris () pop_estack = do i <- getIState@@ -432,27 +434,27 @@     where ptail [] = []           ptail (x : xs) = xs --- | Add a class instance function.+-- | Add an interface implementation function. ----- Precondition: the instance should have the correct type.+-- Precondition: the implementation should have the correct type. ----- Dodgy hack 1: Put integer instances first in the list so they are+-- Dodgy hack 1: Put integer implementations first in the list so they are -- resolved by default. -- -- Dodgy hack 2: put constraint chasers (ParentN) last-addInstance :: Bool -- ^ whether the name is an Integer instance-            -> Bool -- ^ whether to include the instance in instance search-            -> Name -- ^ the name of the class-            -> Name -- ^ the name of the instance-            -> Idris ()-addInstance int res n i+addImplementation :: Bool -- ^ whether the name is an Integer implementation+                  -> Bool -- ^ whether to include the implementation in implementation search+                  -> Name -- ^ the name of the interface+                  -> Name -- ^ the name of the implementation+                  -> Idris ()+addImplementation int res n i     = do ist <- getIState-         case lookupCtxt n (idris_classes ist) of+         case lookupCtxt n (idris_interfaces ist) of                 [CI a b c d e ins fds] ->-                     do let cs = addDef n (CI a b c d e (addI i ins) fds) (idris_classes ist)-                        putIState $ ist { idris_classes = cs }-                _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [(i, res)] []) (idris_classes ist)-                        putIState $ ist { idris_classes = cs }+                     do let cs = addDef n (CI a b c d e (addI i ins) fds) (idris_interfaces ist)+                        putIState $ ist { idris_interfaces = cs }+                _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [(i, res)] []) (idris_interfaces ist)+                        putIState $ ist { idris_interfaces = cs }   where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]         addI i ins | int = (i, res) : ins                    | chaser n = ins ++ [(i, res)]@@ -465,7 +467,7 @@         chaser (NS n _) = chaser n         chaser _ = False --- | Add a privileged implementation - one which instance search will+-- | Add a privileged implementation - one which implementation search will -- happily resolve immediately if it is type correct This is used for -- naming parent implementations when defining an implementation with -- constraints.  Returns the old list, so we can revert easily at the@@ -491,13 +493,13 @@ getOpenImpl = do ist <- getIState                  return (idris_openimpls ist) -addClass :: Name -> ClassInfo -> Idris ()-addClass n i+addInterface :: Name -> InterfaceInfo -> Idris ()+addInterface n i    = do ist <- getIState-        let i' = case lookupCtxt n (idris_classes ist) of-                      [c] -> c { class_instances = class_instances i }+        let i' = case lookupCtxt n (idris_interfaces ist) of+                      [c] -> c { interface_implementations = interface_implementations i }                       _ -> i-        putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }+        putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }  addRecord :: Name -> RecordInfo -> Idris () addRecord n ri = do ist <- getIState@@ -1062,6 +1064,23 @@                    let optdirs = opt_importdirs (idris_options i)                    return ("." : reverse optdirs) +addSourceDir :: FilePath -> Idris ()+addSourceDir fp = do i <- getIState+                     let opts = idris_options i+                     let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts  }+                     putIState $ i { idris_options = opts' }++setSourceDirs :: [FilePath] -> Idris ()+setSourceDirs fps = do i <- getIState+                       let opts = idris_options i+                       let opts' = opts { opt_sourcedirs = nub $ fps  }+                       putIState $ i { idris_options = opts' }++allSourceDirs :: Idris [FilePath]+allSourceDirs = do i <- getIState+                   let optdirs = opt_sourcedirs (idris_options i)+                   return ("." : reverse optdirs)+ colourise :: Idris Bool colourise = do i <- getIState                return $ idris_colourRepl i@@ -1334,8 +1353,8 @@ --                (map (expandParamsD ist dec ps ns) pds) expandParamsD rhs ist dec ps ns (PMutual f pds)    = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)-expandParamsD rhs ist dec ps ns (PClass doc info f cs n nfc params pDocs fds decls cn cd)-   = PClass doc info f+expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)+   = PInterface doc info f            (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)            n nfc            (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)@@ -1344,27 +1363,27 @@            (map (expandParamsD rhs ist dec ps ns) decls)            cn            cd-expandParamsD rhs ist dec ps ns (PInstance doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)+expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)    = let cn' = case cn of                     Just n -> if n `elem` ns then Just (dec n) else Just n                     Nothing -> Nothing in-     PInstance doc argDocs info f-           (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)-           pnames acc opts n-           nfc-           (map (expandParams dec ps ns []) params)-           (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)-           (expandParams dec ps ns [] ty)-           cn'-           (map (expandParamsD True ist dec ps ns) decls)+     PImplementation doc argDocs info f+                     (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)+                     pnames acc opts n+                     nfc+                     (map (expandParams dec ps ns []) params)+                     (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)+                     (expandParams dec ps ns [] ty)+                     cn'+                     (map (expandParamsD True ist dec ps ns) decls) expandParamsD rhs ist dec ps ns d = d  mapsnd f (x, t) = (x, f t) -expandInstanceScope ist dec ps ns (PInstance doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)-    = PInstance doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)-                ty cn decls-expandInstanceScope ist dec ps ns d = d+expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)+    = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)+                      ty cn decls+expandImplementationScope ist dec ps ns d = d  -- | Calculate a priority for a type, for deciding elaboration order -- * if it's just a type variable or concrete type, do it early (0)@@ -1457,7 +1476,7 @@     freeArgNames tm = let (_, args) = unApply tm in                           concatMap freeNames args -    -- if a name appears in a type class or tactic implicit index, it doesn't+    -- if a name appears in an interface or tactic implicit index, it doesn't     -- affect its 'uniquely inferrable' from a static status since these are     -- resolved by searching.     searchArg (Constraint _ _) = True@@ -1757,7 +1776,7 @@ -- | Add the implicit arguments to applications in the term [Name] -- gives the names to always expend, even when under a binder of that -- name (this is to expand methods with implicit arguments in--- dependent type classes).+-- dependent interfaces). addImpl :: [Name] -> IState -> PTerm -> PTerm addImpl = addImpl' False [] [] @@ -2256,7 +2275,6 @@     match (PTactics _) _ = return []     match (PResolveTC _) (PResolveTC _) = return []     match (PTrue _ _) (PTrue _ _) = return []-    match (PReturn _) (PReturn _) = return []     match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'                                                  ms <- match' s s'                                                  return (mt ++ ms)@@ -2496,3 +2514,128 @@   mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)    mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm+++getFile :: Opt -> Maybe String+getFile (Filename str) = Just str+getFile _ = Nothing++getBC :: Opt -> Maybe String+getBC (BCAsm str) = Just str+getBC _ = Nothing++getOutput :: Opt -> Maybe String+getOutput (Output str) = Just str+getOutput _ = Nothing++getIBCSubDir :: Opt -> Maybe String+getIBCSubDir (IBCSubDir str) = Just str+getIBCSubDir _ = Nothing++getImportDir :: Opt -> Maybe String+getImportDir (ImportDir str) = Just str+getImportDir _ = Nothing++getSourceDir :: Opt -> Maybe String+getSourceDir (SourceDir str) = Just str+getSourceDir _ = Nothing++getPkgDir :: Opt -> Maybe String+getPkgDir (Pkg str) = Just str+getPkgDir _ = Nothing++getPkg :: Opt -> Maybe (Bool, String)+getPkg (PkgBuild str) = Just (False, str)+getPkg (PkgInstall str) = Just (True, str)+getPkg _ = Nothing++getPkgClean :: Opt -> Maybe String+getPkgClean (PkgClean str) = Just str+getPkgClean _ = Nothing++getPkgREPL :: Opt -> Maybe String+getPkgREPL (PkgREPL str) = Just str+getPkgREPL _ = Nothing++getPkgCheck :: Opt -> Maybe String+getPkgCheck (PkgCheck str) = Just str+getPkgCheck _              = Nothing++-- | Returns None if given an Opt which is not PkgMkDoc+--   Otherwise returns Just x, where x is the contents of PkgMkDoc+getPkgMkDoc :: Opt          -- ^ Opt to extract+            -> Maybe String -- ^ Result+getPkgMkDoc (PkgMkDoc str) = Just str+getPkgMkDoc _              = Nothing++getPkgTest :: Opt          -- ^ the option to extract+           -> Maybe String -- ^ the package file to test+getPkgTest (PkgTest f) = Just f+getPkgTest _ = Nothing++getCodegen :: Opt -> Maybe Codegen+getCodegen (UseCodegen x) = Just x+getCodegen _ = Nothing++getCodegenArgs :: Opt -> Maybe String+getCodegenArgs (CodegenArgs args) = Just args+getCodegenArgs _ = Nothing++getConsoleWidth :: Opt -> Maybe ConsoleWidth+getConsoleWidth (UseConsoleWidth x) = Just x+getConsoleWidth _ = Nothing+++getExecScript :: Opt -> Maybe String+getExecScript (InterpretScript expr) = Just expr+getExecScript _ = Nothing++getPkgIndex :: Opt -> Maybe FilePath+getPkgIndex (PkgIndex file) = Just file+getPkgIndex _ = Nothing++getEvalExpr :: Opt -> Maybe String+getEvalExpr (EvalExpr expr) = Just expr+getEvalExpr _ = Nothing++getOutputTy :: Opt -> Maybe OutputType+getOutputTy (OutputTy t) = Just t+getOutputTy _ = Nothing++getLanguageExt :: Opt -> Maybe LanguageExt+getLanguageExt (Extension e) = Just e+getLanguageExt _ = Nothing++getTriple :: Opt -> Maybe String+getTriple (TargetTriple x) = Just x+getTriple _ = Nothing++getCPU :: Opt -> Maybe String+getCPU (TargetCPU x) = Just x+getCPU _ = Nothing++getOptLevel :: Opt -> Maybe Int+getOptLevel (OptLevel x) = Just x+getOptLevel _ = Nothing++getOptimisation :: Opt -> Maybe (Bool,Optimisation)+getOptimisation (AddOpt p)    = Just (True,  p)+getOptimisation (RemoveOpt p) = Just (False, p)+getOptimisation _             = Nothing++getColour :: Opt -> Maybe Bool+getColour (ColourREPL b) = Just b+getColour _ = Nothing++getClient :: Opt -> Maybe String+getClient (Client x) = Just x+getClient _ = Nothing++-- Get the first valid port+getPort :: [Opt] -> Maybe REPLPort+getPort []            = Nothing+getPort (Port p : xs) = Just p+getPort (_      : xs) = getPort xs++opt :: (Opt -> Maybe a) -> [Opt] -> [a]+opt = mapMaybe
src/Idris/AbsSyntaxTree.hs view
@@ -49,6 +49,7 @@ import Data.Typeable import Data.Foldable (Foldable) import GHC.Generics (Generic)+import Network.Socket(PortNumber)  import Debug.Trace @@ -103,6 +104,7 @@   , opt_outputTy     :: OutputType   , opt_ibcsubdir    :: FilePath   , opt_importdirs   :: [FilePath]+  , opt_sourcedirs   :: [FilePath]   , opt_triple       :: String   , opt_cpu          :: String   , opt_cmdline      :: [Opt]          -- ^ remember whole command line@@ -131,6 +133,7 @@                       , opt_outputTy   = Executable                       , opt_ibcsubdir  = ""                       , opt_importdirs = []+                      , opt_sourcedirs = []                       , opt_triple     = ""                       , opt_cpu        = ""                       , opt_cmdline    = []@@ -162,7 +165,7 @@     ppopt_impl = False   , ppopt_desugarnats = False   , ppopt_pinames = False-  , ppopt_depth = Just 200+  , ppopt_depth = Nothing   }  -- | Pretty printing options with the most verbosity.@@ -171,7 +174,7 @@     ppopt_impl = True   , ppopt_desugarnats = True   , ppopt_pinames = True-  , ppopt_depth = Just 200+  , ppopt_depth = Nothing   }  -- | Get pretty printing options from the big options record.@@ -214,7 +217,7 @@   , idris_infixes      :: [FixDecl]          -- ^ Currently defined infix operators   , idris_implicits    :: Ctxt [PArg]   , idris_statics      :: Ctxt [Bool]-  , idris_classes      :: Ctxt ClassInfo+  , idris_interfaces   :: Ctxt InterfaceInfo   , idris_openimpls    :: [Name]             -- ^ Privileged implementations, will resolve immediately   , idris_records      :: Ctxt RecordInfo   , idris_dsls         :: Ctxt DSL@@ -295,7 +298,7 @@   , idris_repl_defs              :: [Name]    -- | Stack of names currently being elaborated, Bool set if it's an-  -- instance (instances appear twice; also as a funtion name)+  -- implementation (implementations appear twice; also as a funtion name)   , elab_stack                   :: [(Name, Bool)]  @@ -318,7 +321,6 @@     deriving (Show, Eq, Generic) {-! deriving instance Binary SizeChange-deriving instance NFData SizeChange !-}  type SCGEntry = (Name, [Maybe (Int, SizeChange)])@@ -331,7 +333,6 @@   } deriving (Show, Generic) {-! deriving instance Binary CGInfo-deriving instance NFData CGInfo !-}  primDefs = [ sUN "unsafePerformPrimIO"@@ -345,9 +346,9 @@ data IBCWrite = IBCFix FixDecl               | IBCImp Name               | IBCStatic Name-              | IBCClass Name+              | IBCInterface Name               | IBCRecord Name-              | IBCInstance Bool Bool Name Name+              | IBCImplementation Bool Bool Name Name               | IBCDSL Name               | IBCData Name               | IBCOpt Name@@ -356,6 +357,7 @@               | IBCKeyword String               | IBCImport (Bool, FilePath) -- ^ True = import public               | IBCImportDir FilePath+              | IBCSourceDir FilePath               | IBCObj Codegen FilePath               | IBCLib Codegen String               | IBCCGFlag Codegen String@@ -425,85 +427,11 @@ data Codegen = Via IRFormat String              | Bytecode     deriving (Show, Eq, Generic)-{-!-deriving instance NFData Codegen-!-}  data IRFormat = IBCFormat | JSONFormat deriving (Show, Eq, Generic)  data HowMuchDocs = FullDocs | OverviewDocs --- | REPL commands-data Command = Quit-             | Help-             | Eval PTerm-             | NewDefn [PDecl] -- ^ Each 'PDecl' should be either a type declaration (at most one) or a clause defining the same name.-             | Undefine [Name]-             | Check PTerm-             | Core PTerm-             | DocStr (Either Name Const) HowMuchDocs-             | TotCheck Name-             | Reload-             | Watch-             | Load FilePath (Maybe Int) -- up to maximum line number-             | ChangeDirectory FilePath-             | ModImport String-             | Edit-             | Compile Codegen String-             | Execute PTerm-             | ExecVal PTerm-             | Metavars-             | Prove Bool Name -- ^ If false, use prover, if true, use elab shell-             | AddProof (Maybe Name)-             | RmProof Name-             | ShowProof Name-             | Proofs-             | Universes-             | LogLvl Int-             | LogCategory [LogCat]-             | Spec PTerm-             | WHNF PTerm-             | TestInline PTerm-             | Defn Name-             | Missing Name-             | DynamicLink FilePath-             | ListDynamic-             | Pattelab PTerm-             | Search [String] PTerm-             | CaseSplitAt Bool Int Name-             | AddClauseFrom Bool Int Name-             | AddProofClauseFrom Bool Int Name-             | AddMissing Bool Int Name-             | MakeWith Bool Int Name-             | MakeCase Bool Int Name-             | MakeLemma Bool Int Name-             | DoProofSearch Bool   -- update file-                             Bool   -- recursive search-                             Int    -- depth-                             Name   -- top level name-                             [Name] -- hints-             | SetOpt Opt-             | UnsetOpt Opt-             | NOP-             | SetColour ColourType IdrisColour-             | ColourOn-             | ColourOff-             | ListErrorHandlers-             | SetConsoleWidth ConsoleWidth-             | SetPrinterDepth (Maybe Int)-             | Apropos [String] String-             | WhoCalls Name-             | CallsWho Name-             | Browse [String]-             | MakeDoc String -- IdrisDoc-             | Warranty-             | PrintDef Name-             | PPrint OutputFmt Int PTerm-             | TransformInfo Name-             -- Debugging commands-             | DebugInfo Name-             | DebugUnify PTerm PTerm- data OutputFmt = HTMLOutput | LaTeXOutput  -- | Recognised logging categories for the Idris compiler.@@ -544,12 +472,25 @@     , (strLogCat IIBC)     ] ++data ElabShellCmd = EQED+                  | EAbandon+                  | EUndo+                  | EProofState+                  | EProofTerm+                  | EEval PTerm+                  | ECheck PTerm+                  | ESearch PTerm+                  | EDocStr (Either Name Const)+  deriving (Show, Eq)+ data Opt = Filename String          | Quiet          | NoBanner          | ColourREPL Bool          | Idemode          | IdemodeSocket+         | ShowAll          | ShowLibs          | ShowLibdir          | ShowIncs@@ -574,9 +515,10 @@          | ErrContext          | ShowImpl          | Verbose-         | Port String -- ^ REPL TCP port+         | Port REPLPort -- ^ REPL TCP port          | IBCSubDir String          | ImportDir String+         | SourceDir String          | PkgBuild String          | PkgInstall String          | PkgClean String@@ -612,16 +554,8 @@          | NoOldTacticDeprecationWarnings -- ^ Don't show deprecation warnings for old-style tactics     deriving (Show, Eq, Generic) -data ElabShellCmd = EQED-                  | EAbandon-                  | EUndo-                  | EProofState-                  | EProofTerm-                  | EEval PTerm-                  | ECheck PTerm-                  | ESearch PTerm-                  | EDocStr (Either Name Const)-  deriving (Show, Eq)+data REPLPort = DontListen | ListenPort PortNumber+  deriving (Eq, Generic, Show)  -- Parsed declarations @@ -632,7 +566,6 @@     deriving (Eq, Generic) {-! deriving instance Binary Fixity-deriving instance NFData Fixity !-}  instance Show Fixity where@@ -649,7 +582,6 @@  {-! deriving instance Binary FixDecl-deriving instance NFData FixDecl !-}  instance Ord FixDecl where@@ -660,7 +592,6 @@   deriving (Show, Eq, Data, Generic, Typeable) {-! deriving instance Binary Static-deriving instance NFData Static !-}  -- ^ Mark bindings with their explicitness, and laziness@@ -685,7 +616,6 @@  {-! deriving instance Binary Plicity-deriving instance NFData Plicity !-}  is_scoped :: Plicity -> Maybe ImplicitInfo@@ -712,7 +642,7 @@            | TotalFn | PartialFn | CoveringFn            | Coinductive | AssertTotal -           -- | type class dictionary, eval only when a function+           -- | interface dictionary, eval only when a function            -- argument, and further evaluation results.            | Dictionary            | Implicit                       -- ^ implicit coercion@@ -725,10 +655,10 @@            | Constructor -- ^ Data constructor type            | AutoHint    -- ^ use in auto implicit search            | PEGenerated -- ^ generated by partial evaluator+           | StaticFn    -- ^ Marked static, to be evaluated by partial evaluator     deriving (Show, Eq, Generic) {-! deriving instance Binary FnOpt-deriving instance NFData FnOpt !-}  type FnOpts = [FnOpt]@@ -748,7 +678,7 @@ type ProvideWhat = ProvideWhat' PTerm  -- | Top-level declarations such as compiler directives, definitions,--- datatypes and typeclasses.+-- datatypes and interfaces. data PDecl' t    -- | Fixity declaration    = PFix FC Fixity [String]@@ -781,37 +711,37 @@              (Docstring (Either Err t)) -- Constructor doc              SyntaxInfo -- Constructor SyntaxInfo -   -- | Type class: arguments are documentation, syntax info, source-   -- location, constraints, class name, class name location,+   -- | Interface: arguments are documentation, syntax info, source+   -- location, constraints, interface name, interface name location,    -- parameters, method declarations, optional constructor name-   | PClass (Docstring (Either Err t)) SyntaxInfo FC+   | PInterface (Docstring (Either Err t)) SyntaxInfo FC             [(Name, t)]                        -- constraints-            Name                               -- class name-            FC                                 -- accurate location of class name+            Name                               -- interface name+            FC                                 -- accurate location of interface name             [(Name, FC, t)]                    -- parameters and precise locations             [(Name, Docstring (Either Err t))] -- parameter docstrings             [(Name, FC)]                       -- determining parameters and precise locations             [PDecl' t]                         -- declarations-            (Maybe (Name, FC))                 -- instance constructor name and location-            (Docstring (Either Err t))         -- instance constructor docs+            (Maybe (Name, FC))                 -- implementation constructor name and location+            (Docstring (Either Err t))         -- implementation constructor docs -   -- | Instance declaration: arguments are documentation, syntax-   -- info, source location, constraints, class name, parameters, full-   -- instance type, optional explicit name, and definitions-   | PInstance (Docstring (Either Err t))         -- Instance docs-               [(Name, Docstring (Either Err t))] -- Parameter docs-               SyntaxInfo-               FC [(Name, t)]                     -- constraints-               [Name]                             -- parent dictionaries to search for constraints-               Accessibility-               FnOpts-               Name                               -- class-               FC                                 -- precise location of class-               [t]                                -- parameters-               [(Name, t)]                        -- Extra names in scope in the body-               t                                  -- full instance type-               (Maybe Name)                       -- explicit name-               [PDecl' t]+   -- | Implementation declaration: arguments are documentation, syntax+   -- info, source location, constraints, interface name, parameters, full+   -- Implementation type, optional explicit name, and definitions+   | PImplementation (Docstring (Either Err t))         -- Implementation docs+                     [(Name, Docstring (Either Err t))] -- Parameter docs+                     SyntaxInfo+                     FC [(Name, t)]                     -- constraints+                     [Name]                             -- parent dictionaries to search for constraints+                     Accessibility+                     FnOpts+                     Name                               -- interface+                     FC                                 -- precise location of interface+                     [t]                                -- parameters+                     [(Name, t)]                        -- Extra names in scope in the body+                     t                                  -- full Implementation type+                     (Maybe Name)                       -- explicit name+                     [PDecl' t]    | PDSL     Name (DSL' t) -- ^ DSL declaration    | PSyntax  FC Syntax     -- ^ Syntax definition    | PMutual  FC [PDecl' t] -- ^ Mutual block@@ -831,7 +761,6 @@  deriving (Functor, Generic) {-! deriving instance Binary PDecl'-deriving instance NFData PDecl' !-}  -- | The set of source directives@@ -861,7 +790,7 @@ -- after a term elaboration when there's been reflected elaboration. data RDeclInstructions = RTyDeclInstrs Name FC [PArg] Type                        | RClausesInstrs Name [([(Name, Term)], Term, Term)]-                       | RAddInstance Name Name+                       | RAddImplementation Name Name                        | RDatatypeDeclInstrs Name [PArg]                        -- | Datatype, constructors                        | RDatatypeDefnInstrs Name Type [(Name, [PArg], Type)]@@ -903,7 +832,6 @@     deriving (Functor, Generic) {-! deriving instance Binary PClause'-deriving instance NFData PClause' !-}  -- | Data declaration@@ -933,7 +861,6 @@   PLaterdecl n (g nfc) (mapPTermFC f g tycon) {-! deriving instance Binary PData'-deriving instance NFData PData' !-}  -- Handy to get a free function for applying PTerm -> PTerm functions@@ -977,22 +904,22 @@             (fmap (\(ctorN, ctorNFC) -> (ctorN, g ctorNFC)) ctor)             ctorDoc             syn'-mapPDeclFC f g (PClass doc syn fc constrs n nfc params paramDocs det body ctor ctorDoc) =-    PClass doc syn (f fc)+mapPDeclFC f g (PInterface doc syn fc constrs n nfc params paramDocs det body ctor ctorDoc) =+    PInterface doc syn (f fc)            (map (\(constrn, constr) -> (constrn, mapPTermFC f g constr)) constrs)            n (g nfc) (map (\(n, nfc, pty) -> (n, g nfc, mapPTermFC f g pty)) params)            paramDocs (map (\(dn, dnfc) -> (dn, g dnfc)) det)            (map (mapPDeclFC f g) body)            (fmap (\(n, nfc) -> (n, g nfc)) ctor)            ctorDoc-mapPDeclFC f g (PInstance doc paramDocs syn fc constrs pnames cn acc opts cnfc params pextra instTy instN body) =-    PInstance doc paramDocs syn (f fc)-              (map (\(constrN, constrT) -> (constrN, mapPTermFC f g constrT)) constrs)-              pnames cn acc opts (g cnfc) (map (mapPTermFC f g) params)-              (map (\(en, et) -> (en, mapPTermFC f g et)) pextra)-              (mapPTermFC f g instTy)-              instN-              (map (mapPDeclFC f g) body)+mapPDeclFC f g (PImplementation doc paramDocs syn fc constrs pnames cn acc opts cnfc params pextra implTy implN body) =+    PImplementation doc paramDocs syn (f fc)+                    (map (\(constrN, constrT) -> (constrN, mapPTermFC f g constrT)) constrs)+                    pnames cn acc opts (g cnfc) (map (mapPTermFC f g) params)+                    (map (\(en, et) -> (en, mapPTermFC f g et)) pextra)+                    (mapPTermFC f g implTy)+                    implN+                    (map (mapPDeclFC f g) body) mapPDeclFC f g (PDSL n dsl) = PDSL n (fmap (mapPTermFC f g) dsl) mapPDeclFC f g (PSyntax fc syn) = PSyntax (f fc) $                                     case syn of@@ -1029,8 +956,8 @@ declared (POpenInterfaces _ _ ds) = concatMap declared ds declared (PNamespace _ _ ds) = concatMap declared ds declared (PRecord _ _ _ _ n  _ _ _ _ cn _ _) = n : map fst (maybeToList cn)-declared (PClass _ _ _ _ n _ _ _ _ ms cn cd) = n : (map fst (maybeToList cn) ++ concatMap declared ms)-declared (PInstance _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)+declared (PInterface _ _ _ _ n _ _ _ _ ms cn cd) = n : (map fst (maybeToList cn) ++ concatMap declared ms)+declared (PImplementation _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)     = case mn of            Nothing -> []            Just n -> [n]@@ -1053,8 +980,8 @@ tldeclared (POpenInterfaces _ _ ds)               = concatMap tldeclared ds tldeclared (PMutual _ ds)                         = concatMap tldeclared ds tldeclared (PNamespace _ _ ds)                    = concatMap tldeclared ds-tldeclared (PClass _ _ _ _ n _ _ _ _ ms cn _)     = n : (map fst (maybeToList cn) ++ concatMap tldeclared ms)-tldeclared (PInstance _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)+tldeclared (PInterface _ _ _ _ n _ _ _ _ ms cn _)     = n : (map fst (maybeToList cn) ++ concatMap tldeclared ms)+tldeclared (PImplementation _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)     = case mn of            Nothing -> []            Just n -> [n]@@ -1073,8 +1000,8 @@ defined (POpenInterfaces _ _ ds)                  = concatMap defined ds defined (PNamespace _ _ ds)                       = concatMap defined ds defined (PRecord _ _ _ _ n _ _ _ _ cn _ _)        = n : map fst (maybeToList cn)-defined (PClass _ _ _ _ n _ _ _ _ ms cn _)        = n : (map fst (maybeToList cn) ++ concatMap defined ms)-defined (PInstance _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)+defined (PInterface _ _ _ _ n _ _ _ _ ms cn _)        = n : (map fst (maybeToList cn) ++ concatMap defined ms)+defined (PImplementation _ _ _ _ _ _ _ _ _ _ _ _ _ mn _)     = case mn of            Nothing -> []            Just n -> [n]@@ -1131,7 +1058,7 @@            | PIfThenElse FC PTerm PTerm PTerm    -- ^ Conditional expressions - elaborated to an overloading of ifThenElse            | PCase FC PTerm [(PTerm, PTerm)]     -- ^ A case expression. Args are source location, scrutinee, and a list of pattern/RHS pairs            | PTrue FC PunInfo                    -- ^ Unit type..?-           | PResolveTC FC                       -- ^ Solve this dictionary by type class resolution+           | PResolveTC FC                       -- ^ Solve this dictionary by interface resolution            | PRewrite FC (Maybe Name) PTerm PTerm (Maybe PTerm)              -- ^ "rewrite" syntax, with optional rewriting function and              -- optional result type@@ -1147,13 +1074,12 @@            | PAlternative [(Name, Name)] PAltType [PTerm] -- ^ (| A, B, C|). Includes unapplied unique name mappings for mkUniqueNames.            | PHidden PTerm                                -- ^ Irrelevant or hidden pattern            | PType FC                                     -- ^ 'Type' type-           | PUniverse Universe                           -- ^ Some universe+           | PUniverse FC Universe                        -- ^ Some universe            | PGoal FC PTerm Name PTerm                    -- ^ quoteGoal, used for %reflection functions            | PConstant FC Const                           -- ^ Builtin types            | Placeholder                                  -- ^ Underscore            | PDoBlock [PDo]                               -- ^ Do notation            | PIdiom FC PTerm                              -- ^ Idiom brackets-           | PReturn FC            | PMetavar FC Name                             -- ^ A metavariable, ?name, and its precise location            | PProof [PTactic]                             -- ^ Proof script            | PTactics [PTactic]                           -- ^ As PProof, but no auto solving@@ -1210,7 +1136,7 @@ mapPTermFC f g (PAlternative ns ty ts)        = PAlternative ns ty (map (mapPTermFC f g) ts) mapPTermFC f g (PHidden t)                    = PHidden (mapPTermFC f g t) mapPTermFC f g (PType fc)                     = PType (f fc)-mapPTermFC f g (PUniverse u)                  = PUniverse u+mapPTermFC f g (PUniverse fc u)               = PUniverse (f fc) u mapPTermFC f g (PGoal fc t1 n t2)             = PGoal (f fc) (mapPTermFC f g t1) n (mapPTermFC f g t2) mapPTermFC f g (PConstant fc c)               = PConstant (f fc) c mapPTermFC f g Placeholder                    = Placeholder@@ -1222,7 +1148,6 @@         mapPDoFC (DoLet fc n nfc t1 t2) = DoLet (f fc) n (g nfc) (mapPTermFC f g t1) (mapPTermFC f g t2)         mapPDoFC (DoLetP fc t1 t2) = DoLetP (f fc) (mapPTermFC f g t1) (mapPTermFC f g t2) mapPTermFC f g (PIdiom fc t)                  = PIdiom (f fc) (mapPTermFC f g t)-mapPTermFC f g (PReturn fc)                   = PReturn (f fc) mapPTermFC f g (PMetavar fc n)                = PMetavar (g fc) n mapPTermFC f g (PProof tacs)                  = PProof (map (fmap (mapPTermFC f g)) tacs) mapPTermFC f g (PTactics tacs)                = PTactics (map (fmap (mapPTermFC f g)) tacs)@@ -1240,7 +1165,6 @@  {-! dg instance Binary PTerm-deriving instance NFData PTerm !-}  mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm@@ -1278,7 +1202,7 @@                 | Unfocus                 | MatchRefine Name                 | LetTac Name t | LetTacTy Name t t-                | Exact t | Compute | Trivial | TCInstance+                | Exact t | Compute | Trivial | TCImplementation                 | ProofSearch Bool Bool Int (Maybe Name)                               [Name] -- allowed local names                               [Name] -- hints@@ -1304,7 +1228,6 @@     deriving (Show, Eq, Functor, Foldable, Traversable, Data, Generic, Typeable) {-! deriving instance Binary PTactic'-deriving instance NFData PTactic' !-} instance Sized a => Sized (PTactic' a) where   size (Intro nms)      = 1 + size nms@@ -1339,7 +1262,7 @@   size Unfocus          = 1   size (MatchRefine x)  = 1 + size x   size (LetTacTy x y z) = 1 + size x + size y + size z-  size TCInstance       = 1+  size TCImplementation       = 1  type PTactic = PTactic' PTerm @@ -1351,7 +1274,6 @@     deriving (Eq, Functor, Data, Generic, Typeable) {-! deriving instance Binary PDo'-deriving instance NFData PDo' !-}  instance Sized a => Sized (PDo' a) where@@ -1405,7 +1327,6 @@  {-! deriving instance Binary PArg'-deriving instance NFData PArg' !-}  pimp n t mach = PImp 1 mach [] n t@@ -1442,7 +1363,7 @@     (fc:_) -> Just fc highestFC (PHidden _)             = Nothing highestFC (PType fc)              = Just fc-highestFC (PUniverse _)           = Nothing+highestFC (PUniverse _ _)         = Nothing highestFC (PGoal fc _ _ _)        = Just fc highestFC (PConstant fc _)        = Just fc highestFC Placeholder             = Nothing@@ -1458,7 +1379,6 @@     getDoFC (DoLetP fc l r)       = fc  highestFC (PIdiom fc _)           = Just fc-highestFC (PReturn fc)            = Just fc highestFC (PMetavar fc _)         = Just fc highestFC (PProof _)              = Nothing highestFC (PTactics _)            = Nothing@@ -1475,20 +1395,19 @@ highestFC (PConstSugar fc _)      = Just fc highestFC (PAppImpl t _)          = highestFC t --- Type class data+-- Interface data -data ClassInfo = CI {-    instanceCtorName           :: Name-  , class_methods              :: [(Name, (Bool, FnOpts, PTerm))] -- ^ flag whether it's a "data" method-  , class_defaults             :: [(Name, (Name, PDecl))]         -- ^ method name -> default impl-  , class_default_superclasses :: [PDecl]-  , class_params               :: [Name]-  , class_instances            :: [(Name, Bool)] -- ^ the Bool is whether to include in instance search, so named instances are excluded-  , class_determiners          :: [Int]+data InterfaceInfo = CI {+    implementationCtorName                   :: Name+  , interface_methods                  :: [(Name, (Bool, FnOpts, PTerm))] -- ^ flag whether it's a "data" method+  , interface_defaults                 :: [(Name, (Name, PDecl))]         -- ^ method name -> default impl+  , interface_default_super_interfaces :: [PDecl]+  , interface_params                   :: [Name]+  , interface_implementations          :: [(Name, Bool)] -- ^ the Bool is whether to include in implementation search, so named implementations are excluded+  , interface_determiners              :: [Int]   } deriving (Show, Generic) {-!-deriving instance Binary ClassInfo-deriving instance NFData ClassInfo+deriving instance Binary InterfaceInfo !-}  -- Record data@@ -1509,7 +1428,6 @@     deriving (Show, Generic) {-! deriving instance Binary FnInfo-deriving instance NFData FnInfo !-}  data OptInfo = Optimise {@@ -1518,13 +1436,11 @@   } deriving (Show, Generic) {-! deriving instance Binary OptInfo-deriving instance NFData OptInfo !-}  -- | Syntactic sugar info data DSL' t = DSL {     dsl_bind    :: t-  , dsl_return  :: t   , dsl_apply   :: t   , dsl_pure    :: t   , dsl_var     :: Maybe t@@ -1536,7 +1452,6 @@   } deriving (Show, Functor, Generic) {-! deriving instance Binary DSL'-deriving instance NFData DSL' !-}  type DSL = DSL' PTerm@@ -1547,7 +1462,6 @@     deriving (Show, Generic) {-! deriving instance Binary SynContext-deriving instance NFData SynContext !-}  data Syntax = Rule [SSymbol] PTerm SynContext@@ -1567,7 +1481,6 @@ syntaxSymbols (DeclRule ss _) = ss {-! deriving instance Binary Syntax-deriving instance NFData Syntax !-}  data SSymbol = Keyword Name@@ -1580,7 +1493,6 @@  {-! deriving instance Binary SSymbol-deriving instance NFData SSymbol !-}  newtype SyntaxRules = SyntaxRules { syntaxRulesList :: [Syntax] }@@ -1602,7 +1514,7 @@         EQ -> ruleSort ss1 ss2         r -> r -    -- Better than creating Ord instance for SSymbol since+    -- Better than creating Ord implementation for SSymbol since     -- in general this ordering does not really make sense.     symCompare (Keyword n1) (Keyword n2)        = compare n1 n2     symCompare (Keyword _) _                    = LT@@ -1625,7 +1537,6 @@     symCompare (SimpleExpr e1) (SimpleExpr e2)  = compare e1 e2  initDSL = DSL (PRef f [] (sUN ">>="))-              (PRef f [] (sUN "return"))               (PRef f [] (sUN "<*>"))               (PRef f [] (sUN "pure"))               Nothing@@ -1641,7 +1552,6 @@     deriving (Show, Eq, Data, Generic, Typeable) {-! deriving instance Binary Using-deriving instance NFData Using !-}  data SyntaxInfo = Syn {@@ -1650,7 +1560,7 @@   , syn_namespace     :: [String]   , no_imp            :: [Name]   , imp_methods       :: [Name]-  -- ^ class methods. When expanding implicits, these should be+  -- ^ interface methods. When expanding implicits, these should be   -- expanded even under binders   , decoration        :: Name -> Name   , inPattern         :: Bool@@ -1664,7 +1574,6 @@   , withAppAllowed    :: Bool   } deriving (Show, Generic) {-!-deriving instance NFData SyntaxInfo deriving instance Binary SyntaxInfo !-} @@ -1785,7 +1694,7 @@  -- Pretty-printing declarations and terms --- These "show" instances render to an absurdly wide screen because inserted line breaks+-- These "show" implementations render to an absurdly wide screen because inserted line breaks -- could interfere with interactive editing, which calls "show".  instance Show PTerm where@@ -1852,7 +1761,7 @@           -> Doc OutputAnnotation prettyImp impl = pprintPTerm impl [] [] [] --- | Serialise something to base64 using its Binary instance.+-- | Serialise something to base64 using its Binary implementation.  -- | Do the right thing for rendering a term in an IState prettyIst ::  IState -> PTerm -> Doc OutputAnnotation@@ -2023,7 +1932,7 @@         , kwd "else" <+> prettySe (decD d) startPrec bnd f         ]     prettySe d p bnd (PHidden tm)         = text "." <> prettySe (decD d) funcAppPrec bnd tm-    prettySe d p bnd (PResolveTC _)       = kwd "%instance"+    prettySe d p bnd (PResolveTC _)       = kwd "%implementation"     prettySe d p bnd (PTrue _ IsType)     = annName unitTy $ text "()"     prettySe d p bnd (PTrue _ IsTerm)     = annName unitCon $ text "()"     prettySe d p bnd (PTrue _ TypeOrTerm) = text "()"@@ -2082,7 +1991,7 @@                     depth d . prettySe (decD d) startPrec bnd)                   empty as     prettySe d p bnd (PType _)        = annotate (AnnType "Type" "The type of types") $ text "Type"-    prettySe d p bnd (PUniverse u)    = annotate (AnnType (show u) "The type of unique types") $ text (show u)+    prettySe d p bnd (PUniverse _ u)  = annotate (AnnType (show u) "The type of unique types") $ text (show u)     prettySe d p bnd (PConstant _ c)  = annotate (AnnConst c) (text (show c))     -- XXX: add pretty for tactics     prettySe d p bnd (PProof ts)      =@@ -2090,7 +1999,6 @@     prettySe d p bnd (PTactics ts)    =       kwd "tactics" <+> lbrace <> ellipsis <> rbrace     prettySe d p bnd (PMetavar _ n)   = annotate (AnnName n (Just MetavarOutput) Nothing Nothing) $  text "?" <> pretty n-    prettySe d p bnd (PReturn f)      = kwd "return"     prettySe d p bnd PImpossible      = kwd "impossible"     prettySe d p bnd Placeholder      = text "_"     prettySe d p bnd (PDoBlock dos)   =@@ -2306,9 +2214,9 @@ showDeclImp o (POpenInterfaces _ ns ps) = text "open" <+> braces (text (show ns) <> line <> showDecls o ps <> line) showDeclImp o (PNamespace n fc ps)  = text "namespace" <+> text n <> braces (line <> showDecls o ps <> line) showDeclImp _ (PSyntax _ syn) = text "syntax" <+> text (show syn)-showDeclImp o (PClass _ _ _ cs n _ ps _ _ ds _ _)+showDeclImp o (PInterface _ _ _ cs n _ ps _ _ ds _ _)    = text "interface" <+> text (show cs) <+> text (show n) <+> text (show ps) <> line <> showDecls o ds-showDeclImp o (PInstance _ _ _ _ cs _ acc _ n _ _ _ t _ ds)+showDeclImp o (PImplementation _ _ _ _ cs _ acc _ n _ _ _ t _ ds)    = text "implementation" <+> text (show cs) <+> text (show n) <+> prettyImp o t <> line <> showDecls o ds showDeclImp _ _ = text "..." -- showDeclImp (PImport o) = "import " ++ o@@ -2407,12 +2315,11 @@   size (PDisamb _ tm)                 = size tm   size (PNoImplicits tm)              = size tm   size (PType _)                      = 1-  size (PUniverse _)                  = 1+  size (PUniverse _ _)                = 1   size (PConstant fc const)           = 1 + size fc + size const   size Placeholder                    = 1   size (PDoBlock dos)                 = 1 + size dos   size (PIdiom fc term)               = 1 + size term-  size (PReturn fc)                   = 1   size (PMetavar _ name)              = 1   size (PProof tactics)               = size tactics   size (PElabError err)               = size err
src/Idris/CaseSplit.hs view
@@ -401,8 +401,8 @@           -> Idris String getClause l fn un fp     = do i <- getIState-         case lookupCtxt un (idris_classes i) of-              [c] -> return (mkClassBodies i (class_methods c))+         case lookupCtxt un (idris_interfaces i) of+              [c] -> return (mkInterfaceBodies i (interface_methods c))               _ -> do ty_in <- getInternalApp fp l                       let ty = case ty_in of                                     PTyped n t -> t@@ -436,8 +436,8 @@                                                           sUN "z"]) used           -- write method declarations, indent with 4 spaces-         mkClassBodies :: IState -> [(Name, (Bool, FnOpts, PTerm))] -> String-         mkClassBodies i ns+         mkInterfaceBodies :: IState -> [(Name, (Bool, FnOpts, PTerm))] -> String+         mkInterfaceBodies i ns              = showSep "\n"                   (zipWith (\(n, (_, _, ty)) m -> "    " ++                             def (show (nsroot n)) ++ " "
src/Idris/Chaser.hs view
@@ -98,9 +98,9 @@    i <- getIState    let file = extractFileName f    ibcsd <- valIBCSubDir i-   ids <- allImportDirs    idrisCatch (do-       fp <- findImport ["."] ibcsd file+       srcds <- allSourceDirs+       fp <- findImport srcds ibcsd file        let parsef = fname fp        case lookup parsef acc of             Just _ -> getImports acc fs
src/Idris/CmdOptions.hs view
@@ -1,20 +1,32 @@ {-| Module      : Idris.CmdOptions-Description : CLI for the Idris executable.-Copyright   :+Description : A parser for the CmdOptions for the Idris executable. License     : BSD3 Maintainer  : The Idris Community. -} {-# LANGUAGE Arrows #-}-module Idris.CmdOptions where+module Idris.CmdOptions+  (+    module Idris.CmdOptions+  , opt+  , getClient, getPkg, getPkgCheck, getPkgClean, getPkgMkDoc+  , getPkgREPL, getPkgTest, getPort, getIBCSubDir+  ) where  import Idris.AbsSyntaxTree-import Idris.REPL+import Idris.AbsSyntax (opt, getClient, getPkg, getPkgCheck, getPkgClean, getPkgMkDoc+  , getPkgREPL, getPkgTest, getPort, getIBCSubDir)+-- import Idris.REPL+import Idris.Info (getIdrisVersion)  import IRTS.CodegenCommon  import Options.Applicative import Options.Applicative.Arrows+import Options.Applicative.Types (ReadM(..))+import Control.Monad.Trans (lift)+import Control.Monad.Trans.Reader (ask)+import Control.Monad.Trans.Except (throwE) import Data.Char import Data.Maybe @@ -22,8 +34,6 @@  import Safe (lastMay) -- import qualified Text.PrettyPrint.ANSI.Leijen as PP  runArgParser :: IO [Opt]@@ -33,9 +43,9 @@                            <> progDescDoc (Just idrisProgDesc)                            <> footerDoc   (Just idrisFooter)                           )-                  return $ preProcOpts opts []+                  return $ preProcOpts opts                where-                 idrisHeader = PP.hsep [PP.text "Idris version", PP.text ver, PP.text ", (C) The Idris Community 2016"]+                 idrisHeader = PP.hsep [PP.text "Idris version", PP.text getIdrisVersion, PP.text ", (C) The Idris Community 2016"]                  idrisProgDesc = PP.vsep [PP.empty,                                           PP.text "Idris is a general purpose pure functional programming language with dependent",                                           PP.text "types. Dependent types allow types to be predicated on values, meaning that",@@ -43,7 +53,7 @@                                           PP.text "It is compiled, with eager evaluation. Its features are influenced by Haskell",                                           PP.text "and ML.",                                           PP.empty,-                                          PP.vsep $ map (\x -> PP.indent 4 (PP.text x)) [+                                          PP.vsep $ map (PP.indent 4 . PP.text) [                                               "+ Full dependent types with dependent pattern matching",                                               "+ Simple case expressions, where-clauses, with-rule",                                               "+ Pattern matching let- and lambda-bindings",@@ -66,12 +76,9 @@                                         PP.empty,                                         PP.indent 4 (PP.text "http://www.idris-lang.org/")] --- pureArgParser :: [String] -> [Opt] pureArgParser args = case getParseResult $ execParserPure (prefs idm) (info parser idm) args of-  Just opts -> preProcOpts opts []+  Just opts -> preProcOpts opts   Nothing -> []  parser :: Parser [Opt]@@ -80,7 +87,6 @@   files <- asA (many $ argument (fmap Filename str) (metavar "FILES")) -< ()   A parseVersion >>> A helper -< (flags ++ files) - parseFlags :: Parser [Opt] parseFlags = many $       flag' NoBanner (long "nobanner" <> help "Suppress the banner")@@ -119,6 +125,7 @@   <|> flag' ErrContext     (long "errorcontext")    -- Show things+  <|> flag' ShowAll         (long "info"        <> help "Display information about installation.")   <|> flag' ShowLoggingCats (long "listlogcats" <> help "Display logging categories")   <|> flag' ShowLibs        (long "link"        <> help "Display link flags")   <|> flag' ShowPkgs        (long "listlibs"    <> help "Display installed libraries")@@ -129,11 +136,12 @@    <|> (IBCSubDir <$> strOption (long "ibcsubdir" <> metavar "FILE" <> help "Write IBC files into sub directory"))   <|> (ImportDir <$> strOption (short 'i' <> long "idrispath" <> help "Add directory to the list of import paths"))+  <|> (SourceDir <$> strOption (long "sourcepath" <> help "Add directory to the list of source search paths"))    <|> flag' WarnOnly (long "warn")    <|> (Pkg  <$> strOption (short 'p' <> long "package" <> help "Add package as a dependency"))-  <|> (Port <$> strOption (long "port" <> metavar "PORT" <> help "REPL TCP port"))+  <|> (Port <$> option portReader (long "port" <> metavar "PORT" <> help "REPL TCP port - pass \"none\" to not bind any port"))    -- Package commands   <|> (PkgBuild   <$> strOption (long "build"    <> metavar "IPKG" <> help "Build package"))@@ -153,14 +161,13 @@   <|> (DumpDefun <$> strOption (long "dumpdefuns"))   <|> (DumpCases <$> strOption (long "dumpcases")) -  <|> ((\s -> UseCodegen $ parseCodegen s) <$> strOption (long "codegen"-                                                       <> metavar "TARGET"-                                                       <> help "Select code generator: C, Javascript, Node and bytecode are bundled with Idris"))-+  <|> (UseCodegen . parseCodegen) <$> strOption (long "codegen"+                                              <> metavar "TARGET"+                                              <> help "Select code generator: C, Javascript, Node and bytecode are bundled with Idris") -  <|> ((\s -> UseCodegen $ Via JSONFormat s) <$> strOption (long "portable-codegen"-                                                         <> metavar "TARGET"-                                                         <> help "Pass the name of the code generator. This option is for codegens that take JSON formatted IR."))+  <|> ((UseCodegen . Via JSONFormat) <$> strOption (long "portable-codegen"+                                                 <> metavar "TARGET"+                                                 <> help "Pass the name of the code generator. This option is for codegens that take JSON formatted IR."))    <|> (CodegenArgs <$> strOption (long "cg-opt"                                <> metavar "ARG"@@ -171,10 +178,10 @@   <|> flag' (InterpretScript "Main.main") (long "execute" <> help "Execute as idris")   <|> (InterpretScript <$> strOption      (long "exec" <> metavar "EXPR" <> help "Execute as idris")) -  <|> ((\s -> Extension $ getExt s) <$> strOption (long "extension"-                                                <> short 'X'-                                                <> metavar "EXT"-                                                <> help "Turn on language extension (TypeProviders or ErrorReflection)"))+  <|> ((Extension . getExt) <$> strOption (long "extension"+                                        <> short 'X'+                                        <> metavar "EXT"+                                        <> help "Turn on language extension (TypeProviders or ErrorReflection)"))    -- Optimisation Levels   <|> flag' (OptLevel 3) (long "O3")@@ -201,30 +208,37 @@   <|> flag' NoElimDeprecationWarnings      (long "no-elim-deprecation-warnings"   <> help "Disable deprecation warnings for %elim")   <|> flag' NoOldTacticDeprecationWarnings (long "no-tactic-deprecation-warnings" <> help "Disable deprecation warnings for the old tactic sublanguage") -  where-    getExt s = case maybeRead s of-      Just ext -> ext-      Nothing -> error ("Unknown extension " ++ s)-    maybeRead = fmap fst . listToMaybe . reads+    where+      getExt :: String -> LanguageExt+      getExt s = fromMaybe (error ("Unknown extension " ++ s)) (maybeRead s)+      maybeRead :: String -> Maybe LanguageExt+      maybeRead = fmap fst . listToMaybe . reads+      portReader :: ReadM REPLPort+      portReader =+        ((ListenPort . fromIntegral) <$> auto) <|>+        (ReadM $ do opt <- ask+                    if map toLower opt == "none"+                      then return $ DontListen+                      else lift $ throwE $ ErrorMsg $+                           "got " <> opt <> " expected port number or \"none\"")  parseVersion :: Parser (a -> a)-parseVersion = infoOption ver (short 'v' <> long "version" <> help "Print version information")+parseVersion = infoOption getIdrisVersion (short 'v' <> long "version" <> help "Print version information") -preProcOpts :: [Opt] -> [Opt] -> [Opt]-preProcOpts []              ys = ys-preProcOpts (NoBuiltins:xs) ys = NoBuiltins : NoPrelude : preProcOpts xs ys-preProcOpts (Output s:xs)   ys = Output s : NoREPL : preProcOpts xs ys-preProcOpts (BCAsm s:xs)    ys = BCAsm s : NoREPL : preProcOpts xs ys-preProcOpts (x:xs)          ys = preProcOpts xs (x:ys)+preProcOpts :: [Opt] -> [Opt]+preProcOpts (NoBuiltins : xs) = NoBuiltins : NoPrelude : preProcOpts xs+preProcOpts (Output s : xs)   = Output s : NoREPL : preProcOpts xs+preProcOpts (BCAsm s : xs)    = BCAsm s : NoREPL : preProcOpts xs+preProcOpts (x:xs)            = x : preProcOpts xs+preProcOpts []                = []  parseCodegen :: String -> Codegen parseCodegen "bytecode" = Bytecode parseCodegen cg         = Via IBCFormat (map toLower cg) - parseLogCats :: Monad m => String -> m [LogCat] parseLogCats s =-    case lastMay (readP_to_S (doParse) s) of+    case lastMay (readP_to_S doParse s) of       Just (xs, _) -> return xs       _            -> fail "Incorrect categories specified"   where@@ -252,11 +266,9 @@ parseConsoleWidth "auto"     = return AutomaticWidth parseConsoleWidth "infinite" = return InfinitelyWide parseConsoleWidth  s =-  case lastMay (readP_to_S (integerReader) s) of+  case lastMay (readP_to_S integerReader s) of      Just (r, _) -> return $ ColsWide r      _           -> fail $ "Cannot parse: " ++ s--  integerReader :: ReadP Int integerReader = do
src/Idris/Completion.hs view
@@ -7,7 +7,7 @@ -} module Idris.Completion (replCompletion, proverCompletion) where -import Idris.Core.Evaluate (ctxtAlist)+import Idris.Core.Evaluate (definitions, ctxtAlist) import Idris.Core.TT  import Idris.AbsSyntax (runIO)@@ -24,11 +24,12 @@ import Data.List import Data.Maybe import Data.Char(toLower)+import qualified Data.Map.Strict as Map+import qualified Data.Text as T  import System.Console.Haskeline import System.Console.ANSI (Color) - commands = [ n | (names, _, _) <- allHelp ++ extraHelp, n <- names ]  tacticArgs :: [(String, Maybe TacticArg)]@@ -36,23 +37,27 @@                             , name <- names ] tactics = map fst tacticArgs --- | Convert a name into a string usable for completion. Filters out names--- that users probably don't want to see.-nameString :: Name -> Maybe String-nameString (UN n)       = Just (str n)-nameString (NS n _)     = nameString n-nameString _            = Nothing---- FIXME: Respect module imports--- Issue #1767 in the issue tracker.---    https://github.com/idris-lang/Idris-dev/issues/1767 -- | Get the user-visible names from the current interpreter state. names :: Idris [String] names = do i <- get            let ctxt = tt_ctxt i-           return . nub $-             mapMaybe (nameString . fst) (ctxtAlist ctxt) +++           return $+             mapMaybe nameString (allNames $ definitions ctxt) ++              "Type" : map fst Idris.Parser.Expr.constants+  where+    -- We need both fully qualified names and identifiers that map to them+    allNames :: Ctxt a -> [Name]+    allNames ctxt =+      let mappings = Map.toList ctxt+      in concatMap (\(name, mapping) -> name : Map.keys mapping) mappings+    -- Convert a name into a string usable for completion. Filters out names+    -- that users probably don't want to see.+    nameString :: Name -> Maybe String+    nameString (UN n)       = Just (str n)+    nameString (NS n ns)    =+      let path = intercalate "." . map T.unpack . reverse $ ns+      in fmap ((path ++ ".") ++) $ nameString n+    nameString _            = Nothing  metavars :: Idris [String] metavars = do i <- get@@ -63,27 +68,50 @@ modules = do i <- get              return $ map show $ imported i +namespaces :: Idris [String]+namespaces = do+  ctxt <- fmap tt_ctxt get+  let names = map fst $ ctxtAlist ctxt+  return $ nub $ catMaybes $ map extractNS names+  where+    extractNS :: Name -> Maybe String+    extractNS (NS n ns) = Just $ intercalate "." . map T.unpack . reverse $ ns+    extractNS _ = Nothing +-- UpTo means if user enters full name then no other completions are shown+-- Full always show other (longer) completions if there are any+data CompletionMode = UpTo | Full deriving Eq -completeWith :: [String] -> String -> [Completion]-completeWith ns n = if uniqueExists-                    then [simpleCompletion n]-                    else map simpleCompletion prefixMatches+completeWithMode :: CompletionMode -> [String] -> String -> [Completion]+completeWithMode mode ns n =+  if uniqueExists || (fullWord && mode == UpTo)+  then [simpleCompletion n]+  else map simpleCompletion prefixMatches     where prefixMatches = filter (isPrefixOf n) ns           uniqueExists = [n] == prefixMatches+          fullWord = n `elem` ns -completeName :: [String] -> String -> Idris [Completion]-completeName extra n = do ns <- names-                          return $ completeWith (extra ++ ns) n+completeWith = completeWithMode Full -completeExpr :: [String] -> CompletionFunc Idris-completeExpr extra = completeWord Nothing (" \t(){}:" ++ opChars) (completeName extra)+completeName :: CompletionMode -> [String] -> CompletionFunc Idris+completeName mode extra = completeWord Nothing (" \t(){}:" ++ completionWhitespace) completeName+  where+    completeName n = do+      ns <- names+      return $ completeWithMode mode (extra ++ ns) n+    -- The '.' needs not to be taken into consideration because it serves as namespace separator+    completionWhitespace = opChars \\ "."  completeMetaVar :: CompletionFunc Idris completeMetaVar = completeWord Nothing (" \t(){}:" ++ opChars) completeM     where completeM m = do mvs <- metavars-                           return $ completeWith mvs m+                           return $ completeWithMode UpTo mvs m +completeNamespace :: CompletionFunc Idris+completeNamespace = completeWord Nothing " \t" completeN+  where completeN n = do ns <- namespaces+                         return $ completeWithMode UpTo ns n+ completeOption :: CompletionFunc Idris completeOption = completeWord Nothing " \t" completeOpt     where completeOpt = return . completeWith (map fst setOptions)@@ -133,16 +161,16 @@ completeCmd :: String -> CompletionFunc Idris completeCmd cmd (prev, next) = fromMaybe completeCmdName $ fmap completeArg $ lookupInHelp cmd     where completeArg FileArg = completeFilename (prev, next)-          completeArg NameArg = completeExpr [] (prev, next) -- FIXME only complete one name+          completeArg NameArg = completeName UpTo [] (prev, next)           completeArg OptionArg = completeOption (prev, next)-          completeArg ModuleArg = noCompletion (prev, next) -- FIXME do later-          completeArg NamespaceArg = noCompletion (prev, next) -- FIXME do later-          completeArg ExprArg = completeExpr [] (prev, next)-          completeArg MetaVarArg = completeMetaVar (prev, next) -- FIXME only complete one name+          completeArg ModuleArg = noCompletion (prev, next)+          completeArg NamespaceArg = completeNamespace (prev, next)+          completeArg ExprArg = completeName Full [] (prev, next)+          completeArg MetaVarArg = completeMetaVar (prev, next)           completeArg ColourArg = completeColour (prev, next)           completeArg NoArg = noCompletion (prev, next)           completeArg ConsoleWidthArg = completeConsoleWidth (prev, next)-          completeArg DeclArg = completeExpr [] (prev, next)+          completeArg DeclArg = completeName Full [] (prev, next)           completeArg PkgArgs = completePkg (prev, next)           completeArg (ManyArgs a) = completeArg a           completeArg (OptionalArg a) = completeArg a@@ -154,7 +182,7 @@ replCompletion :: CompletionFunc Idris replCompletion (prev, next) = case firstWord of                                 ':':cmdName -> completeCmd (':':cmdName) (prev, next)-                                _           -> completeExpr [] (prev, next)+                                _           -> completeName UpTo [] (prev, next)     where firstWord = fst $ break isWhitespace $ dropWhile isWhitespace $ reverse prev  @@ -171,7 +199,7 @@     where completeTacName = return ("", completeWith tactics tac)           completeArg Nothing              = noCompletion (prev, next)           completeArg (Just NameTArg)      = noCompletion (prev, next) -- this is for binding new names!-          completeArg (Just ExprTArg)      = completeExpr as (prev, next)+          completeArg (Just ExprTArg)      = completeName Full as (prev, next)           completeArg (Just StringLitTArg) = noCompletion (prev, next)           completeArg (Just AltsTArg)      = noCompletion (prev, next) -- TODO 
src/Idris/Core/Binary.hs view
@@ -342,9 +342,9 @@                                       put x1                                       put x2                                       put x3-                InstanceN x1 x2 -> do putWord8 1-                                      put x1-                                      put x2+                ImplementationN x1 x2 -> do putWord8 1+                                            put x1+                                            put x2                 ParentN x1 x2 -> do putWord8 2                                     put x1                                     put x2@@ -352,7 +352,7 @@                                  put x1                 CaseN x1 x2 -> do putWord8 4; put x1; put x2                 ElimN x1 -> do putWord8 5; put x1-                InstanceCtorN x1 -> do putWord8 6; put x1+                ImplementationCtorN x1 -> do putWord8 6; put x1                 WithN x1 x2 -> do putWord8 7                                   put x1                                   put x2@@ -368,7 +368,7 @@                            return (WhereN x1 x2 x3)                    1 -> do x1 <- get                            x2 <- get-                           return (InstanceN x1 x2)+                           return (ImplementationN x1 x2)                    2 -> do x1 <- get                            x2 <- get                            return (ParentN x1 x2)@@ -380,7 +380,7 @@                    5 -> do x1 <- get                            return (ElimN x1)                    6 -> do x1 <- get-                           return (InstanceCtorN x1)+                           return (ImplementationCtorN x1)                    7 -> do x1 <- get                            x2 <- get                            return (WithN x1 x2)
src/Idris/Core/CaseTree.hs view
@@ -50,7 +50,6 @@     deriving (Eq, Ord, Functor, Generic) {-! deriving instance Binary SC'-deriving instance NFData SC' !-}  data CaseType = Updatable | Shared@@ -66,7 +65,6 @@     deriving (Show, Eq, Ord, Functor, Generic) {-! deriving instance Binary CaseAlt'-deriving instance NFData CaseAlt' !-}  type CaseAlt = CaseAlt' Term
src/Idris/Core/Elaborate.hs view
@@ -329,10 +329,10 @@         isInj ctxt (Bind _ (Pi _ _ _) sc) = True         isInj ctxt _ = False --- | get instance argument names-get_instances :: Elab' aux [Name]-get_instances = do ES p _ _ <- get-                   return $! (instances (fst p))+-- | get implementation argument names+get_implementations :: Elab' aux [Name]+get_implementations = do ES p _ _ <- get+                         return $! (implementations (fst p))  -- | get auto argument names get_autos :: Elab' aux [(Name, ([FailContext], [Name]))]@@ -539,8 +539,8 @@ deferType :: Name -> Raw -> [Name] -> Elab' aux () deferType n ty ns = processTactic' (DeferType n ty ns) -instanceArg :: Name -> Elab' aux ()-instanceArg n = processTactic' (Instance n)+implementationArg :: Name -> Elab' aux ()+implementationArg n = processTactic' (Implementation n)  autoArg :: Name -> Elab' aux () autoArg n = processTactic' (AutoArg n)@@ -572,10 +572,12 @@        env <- get_env        -- let claims = getArgs ty imps        -- claims <- mkClaims (normalise ctxt env ty) imps []+       -- Count arguments to check if we need to normalise the type+       let usety = if argsOK (finalise ty) imps+                      then finalise ty+                      else normalise ctxt env (finalise ty)        claims <- -- trace (show (fn, imps, ty, map fst env, normalise ctxt env (finalise ty))) $-                 mkClaims (finalise ty)-                          (normalise ctxt env (finalise ty))-                          imps [] (map fst env)+                 mkClaims usety imps [] (map fst env)        ES (p, a) s prev <- get        -- reverse the claims we made so that args go left to right        let n = length (filter not imps)@@ -583,13 +585,17 @@        put (ES (p { holes = h : (reverse (take n hs) ++ drop n hs) }, a) s prev)        return $! claims   where+    argsOK :: Type -> [a] -> Bool+    argsOK (Bind n (Pi _ _ _) sc) (i : is) = argsOK sc is+    argsOK _ (i : is) = False+    argsOK _ [] = True+     mkClaims :: Type   -- ^ The type of the operation being applied-             -> Type   -- ^ Normalised version if we need it              -> [Bool] -- ^ Whether the arguments are implicit              -> [(Name, Name)] -- ^ Accumulator for produced claims              -> [Name] -- ^ Hypotheses              -> Elab' aux [(Name, Name)] -- ^ The names of the arguments and their holes, resp.-    mkClaims (Bind n' (Pi _ t_in _) sc) (Bind _ _ scn) (i : is) claims hs =+    mkClaims (Bind n' (Pi _ t_in _) sc) (i : is) claims hs =         do let t = rebind hs t_in            n <- getNameFrom (mkMN n') --            when (null claims) (start_unify n)@@ -597,11 +603,9 @@            env <- get_env            claim n (forgetEnv (map fst env) t)            when i (movelast n)-           mkClaims sc' scn is ((n', n) : claims) hs-    -- if we run out of arguments, we need the normalised version...-    mkClaims t tn@(Bind _ _ sc) (i : is) cs hs = mkClaims tn tn (i : is) cs hs-    mkClaims t _ [] claims _ = return $! (reverse claims)-    mkClaims _ _ _ _ _+           mkClaims sc' is ((n', n) : claims) hs+    mkClaims t [] claims _ = return $! (reverse claims)+    mkClaims _ _ _ _             | Var n <- fn                    = do ctxt <- get_context                         case lookupTy n ctxt of@@ -891,7 +895,7 @@   = do s <- get        ps <- get_probs        ulog <- getUnifyLog-       ivs <- get_instances+       ivs <- get_implementations        case prunStateT 999999 False ps Nothing t1 s of             OK ((v, _, _), s') -> do put s'                                      return $! v@@ -957,7 +961,7 @@     doAll cs pmax    ((x, msg):xs)        = do s <- get             ps <- get_probs-            ivs <- get_instances+            ivs <- get_implementations             case prunStateT pmax True ps (if constrok then Nothing                                                       else Just ivs) x s of                 OK ((v, newps, probs), s') ->@@ -982,7 +986,7 @@       = case runStateT x s of              OK (v, s'@(ES (p, _) _ _)) ->                  let newps = length (problems p) - length ps-                     ibad = badInstances (instances p) ivs+                     ibad = badImplementations (implementations p) ivs                      newpmax = if newps < 0 then 0 else newps in                  if (newpmax > pmax || (not zok && newps > 0)) -- length ps == 0 && newpmax > 0))                     then case reverse (problems p) of@@ -992,8 +996,8 @@                             else OK ((v, newpmax, problems p), s')              Error e -> Error e   where-    badInstances _ Nothing = False-    badInstances inow (Just ithen) = length inow > length ithen+    badImplementations _ Nothing = False+    badImplementations inow (Just ithen) = length inow > length ithen  debugElaborator :: [ErrorReportPart] -> Elab' aux a debugElaborator msg = do ps <- fmap proof get
src/Idris/Core/Evaluate.hs view
@@ -757,15 +757,6 @@ {-! deriving instance Binary CaseDefs !-}-{-!-deriving instance NFData Def-!-}-{-!-deriving instance NFData CaseInfo-!-}-{-!-deriving instance NFData CaseDefs-!-}  instance Show Def where     show (Function ty tm) = "Function: " ++ show (ty, tm)@@ -794,9 +785,6 @@  data Accessibility = Hidden | Public | Frozen | Private     deriving (Eq, Ord, Generic)-{-!-deriving instance NFData Accessibility-!-}  instance Show Accessibility where   show Public = "public export"@@ -813,17 +801,11 @@               | Unchecked               | Generated     deriving (Eq, Generic)-{-!-deriving instance NFData Totality-!-}  -- | Reasons why a function may not be total data PReason = Other [Name] | Itself | NotCovering | NotPositive | UseUndef Name              | ExternalIO | BelieveMe | Mutual [Name] | NotProductive     deriving (Show, Eq, Generic)-{-!-deriving instance NFData PReason-!-}  instance Show Totality where     show (Total args)= "Total" -- ++ show args ++ " decreasing arguments"@@ -1133,7 +1115,7 @@ lookupDefAcc n mkpublic ctxt     = map mkp $ lookupCtxt n (definitions ctxt)   -- io_bind a special case for REPL prettiness-  where mkp (d, inj, a, _, _) = if mkpublic && (not (n == sUN "io_bind" || n == sUN "io_return"))+  where mkp (d, inj, a, _, _) = if mkpublic && (not (n == sUN "io_bind" || n == sUN "io_pure"))                                    then (d, Public) else (d, a)  lookupDefAccExact :: Name -> Bool -> Context ->@@ -1141,7 +1123,7 @@ lookupDefAccExact n mkpublic ctxt     = fmap mkp $ lookupCtxtExact n (definitions ctxt)   -- io_bind a special case for REPL prettiness-  where mkp (d, inj, a, _, _) = if mkpublic && (not (n == sUN "io_bind" || n == sUN "io_return"))+  where mkp (d, inj, a, _, _) = if mkpublic && (not (n == sUN "io_bind" || n == sUN "io_pure"))                                    then (d, Public) else (d, a)  lookupTotal :: Name -> Context -> [Totality]
src/Idris/Core/Execute.hs view
@@ -443,7 +443,7 @@ pstdin = sUN "prim__stdin" pstdout = sUN "prim__stdout" mkfprim = sUN "mkForeignPrim"-pioret = sUN "prim_io_return"+pioret = sUN "prim_io_pure" piobind = sUN "prim_io_bind" upio = sUN "unsafePerformPrimIO" delay = sUN "Delay"
src/Idris/Core/ProofState.hs view
@@ -32,36 +32,36 @@  import Util.Pretty hiding (fill) -data ProofState = PS { thname   :: Name,-                       holes    :: [Name], -- ^ holes still to be solved-                       usedns   :: [Name], -- ^ used names, don't use again-                       nextname :: Int,    -- ^ name supply, for locally unique names-                       global_nextname :: Int, -- ^ a mirror of the global name supply,-                                               --   for generating things like type tags-                                               --   in reflection-                       pterm    :: ProofTerm,   -- ^ current proof term-                       ptype    :: Type,   -- ^ original goal-                       dontunify :: [Name], -- ^ explicitly given by programmer, leave it-                       unified  :: (Name, [(Name, Term)]),-                       notunified :: [(Name, Term)],-                       dotted   :: [(Name, [Name])], -- ^ dot pattern holes + environment-                                                     -- either hole or something in env must turn up in the 'notunified' list during elaboration-                       solved   :: Maybe (Name, Term),-                       problems :: Fails,-                       injective :: [Name],-                       deferred :: [Name], -- ^ names we'll need to define-                       instances :: [Name], -- ^ instance arguments (for type classes)-                       autos    :: [(Name, ([FailContext], [Name]))], -- ^ unsolved 'auto' implicits with their holes-                       psnames  :: [Name], -- ^ Local names okay to use in proof search-                       previous :: Maybe ProofState, -- ^ for undo-                       context  :: Context,-                       datatypes :: Ctxt TypeInfo,-                       plog     :: String,-                       unifylog :: Bool,-                       done     :: Bool,-                       recents  :: [Name],+data ProofState = PS { thname            :: Name,+                       holes             :: [Name], -- ^ holes still to be solved+                       usedns            :: [Name], -- ^ used names, don't use again+                       nextname          :: Int,    -- ^ name supply, for locally unique names+                       global_nextname   :: Int, -- ^ a mirror of the global name supply,+                                                 --   for generating things like type tags+                                                 --   in reflection+                       pterm             :: ProofTerm, -- ^ current proof term+                       ptype             :: Type,   -- ^ original goal+                       dontunify         :: [Name], -- ^ explicitly given by programmer, leave it+                       unified           :: (Name, [(Name, Term)]),+                       notunified        :: [(Name, Term)],+                       dotted            :: [(Name, [Name])], -- ^ dot pattern holes + environment+                                                              -- either hole or something in env must turn up in the 'notunified' list during elaboration+                       solved            :: Maybe (Name, Term),+                       problems          :: Fails,+                       injective         :: [Name],+                       deferred          :: [Name], -- ^ names we'll need to define+                       implementations   :: [Name], -- ^ implementation arguments (for interfaces)+                       autos             :: [(Name, ([FailContext], [Name]))], -- ^ unsolved 'auto' implicits with their holes+                       psnames           :: [Name], -- ^ Local names okay to use in proof search+                       previous          :: Maybe ProofState, -- ^ for undo+                       context           :: Context,+                       datatypes         :: Ctxt TypeInfo,+                       plog              :: String,+                       unifylog          :: Bool,+                       done              :: Bool,+                       recents           :: [Name],                        while_elaborating :: [FailContext],-                       constraint_ns :: String+                       constraint_ns     :: String                      }  data Tactic = Attack@@ -98,7 +98,7 @@             | Focus Name             | Defer [Name] Name             | DeferType Name Raw [Name]-            | Instance Name+            | Implementation Name             | AutoArg Name             | SetInjective Name             | MoveLast Name@@ -431,14 +431,14 @@                                                   else ps)                            return t -instanceArg :: Name -> RunTactic-instanceArg n ctxt env (Bind x (Hole t) sc)+implementationArg :: Name -> RunTactic+implementationArg n ctxt env (Bind x (Hole t) sc)     = do action (\ps -> let hs = holes ps-                            is = instances ps in+                            is = implementations ps in                             ps { holes = (hs \\ [x]) ++ [x],-                                 instances = x:is })+                                 implementations = x:is })          return (Bind x (Hole t) sc)-instanceArg n ctxt env _+implementationArg n ctxt env _     = fail "The current focus is not a hole."  autoArg :: Name -> RunTactic@@ -600,7 +600,7 @@                             notunified = updateNotunified [(x,val)]                                            (notunified ps),                             recents = x : recents ps,-                            instances = instances ps \\ [x],+                            implementations = implementations ps \\ [x],                             dotted = dropUnified dropdots (dotted ps) })         let (locked, did) = tryLock (holes ps \\ [x]) (updsubst x val sc) in             return locked@@ -1148,7 +1148,7 @@          mktac (Focus n)         = focus n          mktac (Defer ns n)      = defer ns n          mktac (DeferType n t a) = deferType n t a-         mktac (Instance n)      = instanceArg n+         mktac (Implementation n)= implementationArg n          mktac (AutoArg n)       = autoArg n          mktac (SetInjective n)  = setinj n          mktac (MoveLast n)      = movelast n
src/Idris/Core/TT.hs view
@@ -42,10 +42,10 @@   , intTyName, isInjective, isTypeConst, lookupCtxt   , lookupCtxtExact, lookupCtxtName, mapCtxt, mkApp, nativeTyWidth   , nextName, noOccurrence, nsroot, occurrences-  , pEraseType, pmap, pprintRaw, pprintTT, prettyEnv, psubst, pToV-  , pToVs, pureTerm, raw_apply, raw_unapply, refsIn, safeForget+  , pEraseType, pmap, pprintRaw, pprintTT, pprintTTClause, prettyEnv, psubst+  , pToV, pToVs, pureTerm, raw_apply, raw_unapply, refsIn, safeForget   , safeForgetEnv, showCG, showEnv, showEnvDbg, showSep-  , sInstanceN, sMN, sNS, spanFC, str, subst, substNames, substTerm+  , sImplementationN, sMN, sNS, spanFC, str, subst, substNames, substTerm   , substV, sUN, tcname, termSmallerThan, tfail, thead, tnull   , toAlist, traceWhen, txt, unApply, uniqueBinders, uniqueName   , uniqueNameFrom, uniqueNameSet, unList, updateDef, vToP, weakenTm@@ -54,8 +54,8 @@ -- Work around AMP without CPP import Prelude (Eq(..), Show(..), Ord(..), Functor(..), Monad(..), String, Int,                 Integer, Ordering(..), Maybe(..), Num(..), Bool(..), Enum(..),-                Read(..), FilePath, Double, (&&), (||), ($), (.), div, error, fst,-                snd, not, mod, read, otherwise)+                Read(..), FilePath, Double, (&&), (||), ($), (.), div, error, flip,+                fst, snd, not, mod, read, otherwise)  import Control.Applicative (Applicative (..), Alternative) import qualified Control.Applicative as A (Alternative (..))@@ -182,7 +182,6 @@  {-! deriving instance Binary FC-deriving instance NFData FC !-}  instance Sized FC where@@ -246,7 +245,6 @@                 | SourceTerm Term   deriving (Show, Eq, Data, Generic, Typeable) {-!-deriving instance NFData Err deriving instance Binary Err !-} @@ -344,10 +342,6 @@     empty = mzero     (<|>) = mplus -{-!-deriving instance NFData Err-!-}- instance Sized ErrorReportPart where   size (TextPart msg) = 1 + length msg   size (TermPart t) = 1 + size t@@ -499,26 +493,24 @@  {-! deriving instance Binary Name-deriving instance NFData Name !-}  data SpecialName = WhereN !Int !Name !Name                  | WithN !Int !Name-                 | InstanceN !Name [T.Text]+                 | ImplementationN !Name [T.Text]                  | ParentN !Name !T.Text                  | MethodN !Name                  | CaseN !FC' !Name                  | ElimN !Name-                 | InstanceCtorN !Name+                 | ImplementationCtorN !Name                  | MetaN !Name !Name   deriving (Eq, Ord, Data, Generic, Typeable) {-! deriving instance Binary SpecialName-deriving instance NFData SpecialName !-} -sInstanceN :: Name -> [String] -> SpecialName-sInstanceN n ss = InstanceN n (map T.pack ss)+sImplementationN :: Name -> [String] -> SpecialName+sImplementationN n ss = ImplementationN n (map T.pack ss)  sParentN :: Name -> String -> SpecialName sParentN n s = ParentN n (T.pack s)@@ -552,13 +544,13 @@ instance Show SpecialName where     show (WhereN i p c) = show p ++ ", " ++ show c     show (WithN i n) = "with block in " ++ show n-    show (InstanceN cl inst) = showSep ", " (map T.unpack inst) ++ " implementation of " ++ show cl+    show (ImplementationN cl impl) = showSep ", " (map T.unpack impl) ++ " implementation of " ++ show cl     show (MethodN m) = "method " ++ show m     show (ParentN p c) = show p ++ "#" ++ T.unpack c     show (CaseN fc n) = "case block in " ++ show n ++                         if fc == FC' emptyFC then "" else " at " ++ show fc     show (ElimN n) = "<<" ++ show n ++ " eliminator>>"-    show (InstanceCtorN n) = "constructor of " ++ show n+    show (ImplementationCtorN n) = "constructor of " ++ show n     show (MetaN parent meta) = "<<" ++ show parent ++ " " ++ show meta ++ ">>"  -- Show a name in a way decorated for code generation, not human reading@@ -570,12 +562,12 @@ showCG (SN s) = showCG' s   where showCG' (WhereN i p c) = showCG p ++ ":" ++ showCG c ++ ":" ++ show i         showCG' (WithN i n) = "_" ++ showCG n ++ "_with_" ++ show i-        showCG' (InstanceN cl inst) = '@':showCG cl ++ '$':showSep ":" (map T.unpack inst)+        showCG' (ImplementationN cl impl) = '@':showCG cl ++ '$':showSep ":" (map T.unpack impl)         showCG' (MethodN m) = '!':showCG m         showCG' (ParentN p c) = showCG p ++ "#" ++ show c         showCG' (CaseN fc c) = showCG c ++ showFC' fc ++ "_case"         showCG' (ElimN sn) = showCG sn ++ "_elim"-        showCG' (InstanceCtorN n) = showCG n ++ "_ictor"+        showCG' (ImplementationCtorN n) = showCG n ++ "_ictor"         showCG' (MetaN parent meta) = showCG parent ++ "_meta_" ++ showCG meta         showFC' (FC' NoFC) = ""         showFC' (FC' (FileFC f)) = "_" ++ cgFN f@@ -598,10 +590,10 @@ mapCtxt = fmap . fmap  -- |Return True if the argument 'Name' should be interpreted as the name of a--- typeclass.+-- interface. tcname (UN xs) = False tcname (NS n _) = tcname n-tcname (SN (InstanceN _ _)) = True+tcname (SN (ImplementationN _ _)) = True tcname (SN (MethodN _)) = True tcname (SN (ParentN _ _)) = True tcname _ = False@@ -695,11 +687,6 @@  data ArithTy = ATInt IntTy | ATFloat -- TODO: Float vectors https://github.com/idris-lang/Idris-dev/issues/1723     deriving (Show, Eq, Ord, Data, Generic, Typeable)-{-!-deriving instance NFData IntTy-deriving instance NFData NativeTy-deriving instance NFData ArithTy-!-}  instance Pretty ArithTy OutputAnnotation where     pretty (ATInt ITNative) = text "Int"@@ -752,7 +739,6 @@  {-! deriving instance Binary Const-deriving instance NFData Const !-}  isTypeConst :: Const -> Bool@@ -850,16 +836,14 @@  {-! deriving instance Binary Raw-deriving instance NFData Raw !-} -data ImplicitInfo = Impl { tcinstance :: Bool, toplevel_imp :: Bool,+data ImplicitInfo = Impl { tcimplementation :: Bool, toplevel_imp :: Bool,                            machine_gen :: Bool }   deriving (Show, Eq, Ord, Data, Generic, Typeable)  {-! deriving instance Binary ImplicitInfo-deriving instance NFData ImplicitInfo !-}  -- The type parameter `b` will normally be something like `TT Name` or just@@ -910,7 +894,6 @@   deriving (Show, Eq, Ord, Functor, Foldable, Traversable, Data, Generic, Typeable) {-! deriving instance Binary Binder-deriving instance NFData Binder !-}  instance Sized a => Sized (Binder a) where@@ -953,9 +936,6 @@ data UExp = UVar String Int -- ^ universe variable, with source file to disambiguate           | UVal Int -- ^ explicit universe level   deriving (Eq, Ord, Data, Generic, Typeable)-{-!-deriving instance NFData UExp-!-}  instance Sized UExp where   size _ = 1@@ -995,7 +975,6 @@   deriving (Show, Ord, Data, Generic, Typeable) {-! deriving instance Binary NameType-deriving instance NFData NameType !-}  instance Sized NameType where@@ -1035,7 +1014,6 @@   deriving (Ord, Functor, Data, Generic, Typeable) {-! deriving instance Binary TT-deriving instance NFData TT !-}  class TermSize a where@@ -1109,7 +1087,6 @@     deriving (Show, Generic) {-! deriving instance Binary TypeInfo-deriving instance NFData TypeInfo !-}  instance Eq n => Eq (TT n) where@@ -1511,12 +1488,12 @@   where     nextName' (WhereN i f x) = WhereN i f (nextName x)     nextName' (WithN i n) = WithN i (nextName n)-    nextName' (InstanceN n ns) = InstanceN (nextName n) ns+    nextName' (ImplementationN n ns) = ImplementationN (nextName n) ns     nextName' (ParentN n ns) = ParentN (nextName n) ns     nextName' (CaseN fc n) = CaseN fc (nextName n)     nextName' (ElimN n) = ElimN (nextName n)     nextName' (MethodN n) = MethodN (nextName n)-    nextName' (InstanceCtorN n) = InstanceCtorN (nextName n)+    nextName' (ImplementationCtorN n) = ImplementationCtorN (nextName n)     nextName' (MetaN parent meta) = MetaN parent (nextName meta) nextName (SymRef i) = error "Can't generate a name from a symbol reference" @@ -1668,14 +1645,14 @@ -- | Check whether a term has any hole bindings in it - impure if so pureTerm :: TT Name -> Bool pureTerm (App _ f a) = pureTerm f && pureTerm a-pureTerm (Bind n b sc) = notClassName n && pureBinder b && pureTerm sc where+pureTerm (Bind n b sc) = notInterfaceName n && pureBinder b && pureTerm sc where     pureBinder (Hole _) = False     pureBinder (Guess _ _) = False     pureBinder (Let t v) = pureTerm t && pureTerm v     pureBinder t = pureTerm (binderTy t) -    notClassName (MN _ c) | c == txt "__class" = False-    notClassName _ = True+    notInterfaceName (MN _ c) | c == txt "__interface" = False+    notInterfaceName _ = True  pureTerm _ = True @@ -1810,6 +1787,23 @@     bracket outer inner doc       | outer > inner = lparen <> doc <> rparen       | otherwise     = doc++pprintTTClause :: [(Name, Type)] -> Term -> Term -> Doc OutputAnnotation+pprintTTClause pvars lhs rhs =+    vars pvars . group . align $+      pprintTT (map fst pvars) lhs <$>+      text "↦" <$>+      (pprintTT (map fst pvars) rhs)+  where vars [] terms = terms+        vars (v:vs) terms =+          annotate AnnKeyword (text "var") <+>+          group (align (sep (punctuate comma (reverse (bindVars [] (v:vs)))))) <+>+          annotate AnnKeyword (text ".") <$>+          indent 2 terms+        bindVars _ [] = []+        bindVars ns ((n, ty):vs) =+          bindingOf n False <+> colon <+> pprintTT ns ty : bindVars (n:ns) vs+  -- | Pretty-print a raw term. pprintRaw :: [Name] -- ^ Bound names, for highlighting
src/Idris/Core/Unify.hs view
@@ -193,13 +193,13 @@ --           case boundVs (envPos x 0 env) tm of --                [] -> return [(x, tm)] --                (i:_) -> lift $ tfail (UnifyScope x (fst (fst (ns!!i)))---                                      (inst ns tm) (errEnv env))+--                                      (impl ns tm) (errEnv env))         let v = highV (-1) tm in             if v >= length ns                then lift $ tfail (Msg "SCOPE ERROR")                else return [(x, bind v ns tm)]-      where inst [] tm = tm-            inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)+      where impl [] tm = tm+            impl ((n, _) : ns) tm = impl ns (substV (P Bound n Erased) tm)      bind i ns tm       | i < 0 = tm@@ -460,7 +460,7 @@             substEnv ((n, t) : env) tm                 = substEnv env (substV (P Bound n (binderTy t)) tm) -            -- remove any unnecessary lambdas (helps with type class+            -- remove any unnecessary lambdas (helps with interface             -- resolution later).             eta ks (Bind n (Lam ty) sc) = eta ((n, ty) : ks) sc             eta ks t = rebind ks t@@ -488,8 +488,8 @@ --     un' env fn bnames (Bind x (PVTy _) sx) (Bind y (PVTy _) sy) --         = un' env False ((x,y):bnames) sx sy -    -- f D unifies with t -> D. This is dubious, but it helps with type-    -- class resolution for type classes over functions.+    -- f D unifies with t -> D. This is dubious, but it helps with+    -- interface resolution for interfaces over functions.      un' env fn bnames (App _ f x) (Bind n (Pi i t k) y)       | noOccurrence n y && injectiveApp f@@ -667,13 +667,13 @@ --           case boundVs (envPos x 0 env) tm of --                [] -> return [(x, tm)] --                (i:_) -> lift $ tfail (UnifyScope x (fst (fst (ns!!i)))---                                      (inst ns tm) (errEnv env))+--                                      (impl ns tm) (errEnv env))         let v = highV (-1) tm in             if v >= length ns                then lift $ tfail (Msg "SCOPE ERROR")                else return [(x, bind v ns tm)]-      where inst [] tm = tm-            inst (((n, _), _) : ns) tm = inst ns (substV (P Bound n Erased) tm)+      where impl [] tm = tm+            impl (((n, _), _) : ns) tm = impl ns (substV (P Bound n Erased) tm)     checkScope ns (x, tm) = lift $ tfail (Msg "HOLE ERROR")      bind i ns tm
src/Idris/Coverage.hs view
@@ -17,6 +17,7 @@ import Idris.Error import Idris.Output (iWarn, iputStrLn) +import Data.Char import Data.List import Data.Either import Data.Maybe@@ -81,8 +82,9 @@         logCoverage 5 $ "non-concrete args " ++ show (genPH i nty)          logCoverage 5 $ show (lhs_tms, lhss)-        logCoverage 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)-        logCoverage 10 $ show argss ++ "\n" ++ show all_args+        logCoverage 5 $ "Args are: " ++ show argss+        logCoverage 5 $ show (map length argss) ++ "\nAll args:\n" ++ show (map length all_args)+        logCoverage 10 $ "All args are: " ++ show all_args         logCoverage 3 $ "Original: \n" ++              showSep "\n" (map (\t -> showTmImpls (delab' i t True True)) xs)         -- add an infinite supply of explicit arguments to update the possible@@ -203,46 +205,73 @@  genAll :: IState -> (Bool, [PTerm]) -> [PTerm] genAll i (addPH, args)-   = case filter (/=Placeholder) $ fnub (concatMap otherPats (fnub args)) of+   = case filter (/=Placeholder) $ fnub $ mergePHs $ fnub (concatMap otherPats (fnub args)) of           [] -> [Placeholder]-          xs -> ph $ inventConsts xs+          xs -> ph xs   where     ph ts = if addPH then Placeholder : ts else ts -    -- if they're constants, invent a new one to make sure that-    -- constants which are not explicitly handled are covered-    inventConsts cs@(PConstant fc c : _) = map (PConstant NoFC) (ic' (mapMaybe getConst cs))-      where getConst (PConstant _ c) = Just c-            getConst _ = Nothing-    inventConsts xs = xs+    -- Merge patterns with placeholders in other patterns, to ensure we've+    -- covered all possible generated cases+    -- e.g. if we have (True, _) (False, _) (_, True) (_, False) +    -- we should merge these to get (True, True), (False, False)+    -- (False, True) and (True, False)+    mergePHs :: [PTerm] -> [PTerm]+    mergePHs xs = mergePHs' xs xs -    -- try constants until they're not in the list.-    -- FIXME: It is, of course, possible that someone has enumerated all-    -- the constants and matched on them (maybe in generated code) and this-    -- will be really slow. This is sufficiently unlikely that we won't-    -- worry for now...+    mergePHs' [] all = []+    mergePHs' (x : xs) all = mergePH x all ++ mergePHs' xs all -    ic' xs@(I _ : _) = firstMissing xs (lotsOfNums I)-    ic' xs@(BI _ : _) = firstMissing xs (lotsOfNums BI)-    ic' xs@(Fl _ : _) = firstMissing xs (lotsOfNums Fl)-    ic' xs@(B8 _ : _) = firstMissing xs (lotsOfNums B8)-    ic' xs@(B16 _ : _) = firstMissing xs (lotsOfNums B16)-    ic' xs@(B32 _ : _) = firstMissing xs (lotsOfNums B32)-    ic' xs@(B64 _ : _) = firstMissing xs (lotsOfNums B64)-    ic' xs@(Ch _ : _) = firstMissing xs lotsOfChars-    ic' xs@(Str _ : _) = firstMissing xs lotsOfStrings-    -- The rest are types with only one case-    ic' xs = xs+    mergePH :: PTerm -> [PTerm] -> [PTerm]+    mergePH tm [] = []+    mergePH tm (x : xs) +          | Just merged <- mergePTerm tm x = merged : mergePH tm xs+          | otherwise = mergePH tm xs -    firstMissing cs (x : xs) | x `elem` cs = firstMissing cs xs-                             | otherwise = x : cs+    mergePTerm :: PTerm -> PTerm -> Maybe PTerm+    mergePTerm x Placeholder = Just x+    mergePTerm Placeholder x = Just x+    mergePTerm tm@(PRef fc1 hl1 n1) (PRef fc2 hl2 n2)+          | n1 == n2 = Just tm+    mergePTerm (PPair fc1 hl1 p1 x1 y1) (PPair fc2 hl2 p2 x2 y2)+          = do x <- mergePTerm x1 x2+               y <- mergePTerm y1 y2+               Just (PPair fc1 hl1 p1 x y)+    mergePTerm (PDPair fc1 hl1 p1 x1 t1 y1) (PDPair fc2 hl2 p2 x2 t2 y2)+          = do x <- mergePTerm x1 x2+               y <- mergePTerm y1 y2+               t <- mergePTerm t1 t2+               Just (PDPair fc1 hl1 p1 x t y)+    mergePTerm (PApp fc1 f1 args1) (PApp fc2 f2 args2)+          = do fm <- mergePTerm f1 f2+               margs <- mergeArgs args1 args2+               Just (PApp fc1 fm margs)+      where+        mergeArgs [] [] = Just []+        mergeArgs (a : as) (b : bs)+                  = do ma_in <- mergePTerm (getTm a) (getTm b)+                       let ma = a { getTm = ma_in }+                       mas <- mergeArgs as bs+                       Just (ma : mas)+        mergeArgs _ _ = Nothing+    mergePTerm x y | x == y = Just x+                   | otherwise = Nothing -    lotsOfNums t = map t [0..]-    lotsOfChars = map Ch ['a'..]-    lotsOfStrings = map Str (map (("some string " ++).show) [1..])+    -- for every constant in a term (at any level) take next one to make sure+    -- that constants which are not explicitly handled are covered+    nextConst (PConstant fc c) = PConstant NoFC (nc' c)+    nextConst o = o -    nubMap f acc [] = acc-    nubMap f acc (x : xs) = nubMap f (fnub' acc (f x)) xs+    nc' (I c) = I (c + 1)+    nc' (BI c) = BI (c + 1)+    nc' (Fl c) = Fl (c + 1)+    nc' (B8 c) = B8 (c + 1)+    nc' (B16 c) = B16 (c + 1)+    nc' (B32 c) = B32 (c + 1)+    nc' (B64 c) = B64 (c + 1)+    nc' (Ch c) = Ch (chr $ ord c + 1)+    nc' (Str c) = Str (c ++ "'")+    nc' o = o      otherPats :: PTerm -> [PTerm]     otherPats o@(PRef fc hl n) = ph $ ops fc n [] o@@ -257,7 +286,7 @@                 ([pimp (sUN "a") Placeholder True,                   pimp (sUN "P") Placeholder True] ++                  [pexp t,pexp v]) o-    otherPats o@(PConstant _ c) = ph $ inventConsts [o] -- return o+    otherPats o@(PConstant _ c) = ph [o, nextConst o]     otherPats arg = return Placeholder      ops fc n xs o@@ -311,6 +340,7 @@     quickEq :: PTerm -> PTerm -> Bool     quickEq (PConstant _ n) (PConstant _ n') = n == n'     quickEq (PRef _ _ n) (PRef _ _ n') = n == n'+    quickEq (PPair _ _ _ l r) (PPair _ _ _ l' r') = quickEq l l' && quickEq r r'     quickEq (PApp _ t as) (PApp _ t' as')         | length as == length as'            = quickEq t t' && and (zipWith quickEq (map getTm as) (map getTm as'))@@ -489,7 +519,7 @@                   case getPartial ist [] ns of                       Nothing -> return ()-                      Just bad -> do let t' = Partial (Other bad) +                      Just bad -> do let t' = Partial (Other bad)                                      logCoverage 2 $ "Set to " ++ show t'                                      setTotality n t'                                      addIBC (IBCTotal n t')@@ -503,7 +533,7 @@      getPartial ist [] [] = Nothing     getPartial ist bad [] = Just bad-    getPartial ist bad (n : ns) +    getPartial ist bad (n : ns)         = case lookupTotalExact n (tt_ctxt ist) of                Just (Partial _) -> getPartial ist (n : bad) ns                _ -> getPartial ist bad ns@@ -761,12 +791,23 @@ mkMultiPaths ist path [] = [reverse path] mkMultiPaths ist path cg = concatMap extend cg   where extend (nextf, args)-           | (nextf, args) `elem` path = [ reverse ((nextf, args) : path) ]+           | (nextf, args) `inPath` path = [ reverse ((nextf, args) : path) ]            | [Unchecked] <- lookupTotal nextf (tt_ctxt ist)                = case lookupCtxt nextf (idris_callgraph ist) of                     [ncg] -> mkMultiPaths ist ((nextf, args) : path) (scg ncg)                     _ -> [ reverse ((nextf, args) : path) ]            | otherwise = [ reverse ((nextf, args) : path) ]++        inPath :: SCGEntry -> [SCGEntry] -> Bool+        inPath f [] = False+        inPath f (g : gs) = smallerEq f g || f == g || inPath f gs++        smallerEq :: SCGEntry -> SCGEntry -> Bool+        smallerEq (f, args) (g, args')+            = f == g && not (null (filter smallers args))+                     && filter smallers args == filter smallers args'+        smallers (Just (_, Smaller)) = True+        smallers _ = False  -- If any route along the multipath leads to infinite descent, we're fine. -- Try a route beginning with every argument.
src/Idris/DSL.hs view
@@ -95,7 +95,6 @@ expandSugar dsl (PNoImplicits t) = PNoImplicits (expandSugar dsl t) expandSugar dsl (PUnifyLog t) = PUnifyLog (expandSugar dsl t) expandSugar dsl (PDisamb ns t) = PDisamb ns (expandSugar dsl t)-expandSugar dsl (PReturn fc) = dsl_return dsl expandSugar dsl (PRewrite fc by r t ty)     = PRewrite fc by r (expandSugar dsl t) ty expandSugar dsl (PGoal fc r n sc)
src/Idris/DeepSeq.hs view
@@ -22,6 +22,7 @@ import Util.DynamicLinker  import Control.DeepSeq+import Network.Socket(PortNumber)  import qualified Cheapskate.Types as CT import qualified Idris.Docstrings as D@@ -47,6 +48,9 @@ instance NFData IdrisColour where   rnf (IdrisColour _ x2 x3 x4 x5) = rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` () +instance NFData PortNumber where+  rnf x = rnf $ show x+ -- Handle doesn't have an NFData instance instance NFData OutputMode where   rnf (RawOutput x) = ()@@ -57,6 +61,7 @@ instance NFData PrimFn instance NFData SyntaxRules instance NFData Opt+instance NFData REPLPort instance NFData TIData instance NFData IOption instance NFData LanguageExt@@ -91,7 +96,7 @@ instance (NFData t) => NFData (PTactic' t) instance (NFData t) => NFData (PDo' t) instance (NFData t) => NFData (PArg' t)-instance NFData ClassInfo+instance NFData InterfaceInfo instance NFData RecordInfo instance NFData OptInfo instance NFData TypeInfo
src/Idris/Delaborate.hs view
@@ -142,7 +142,7 @@        | toplevel_imp impl -- information in 'imps' repeated           = PPi (Imp [] Dynamic False (Just impl) False) n NoFC (de env [] ty) (de ((n,n):env) is sc)     de env is (Bind n (Pi (Just impl) ty _) sc)-       | tcinstance impl+       | tcimplementation impl           = PPi constraint n NoFC (de env [] ty) (de ((n,n):env) is sc)        | otherwise           = PPi (Imp [] Dynamic False (Just impl) False) n NoFC (de env [] ty) (de ((n,n):env) is sc)@@ -175,7 +175,7 @@     de env _ Erased = Placeholder     de env _ Impossible = Placeholder     de env _ (TType i) = PType un-    de env _ (UType u) = PUniverse u+    de env _ (UType u) = PUniverse un u      dens x | fullname = x     dens ns@(NS n _) = case lookupCtxt n (idris_implicits ist) of
src/Idris/Docs.hs view
@@ -45,18 +45,18 @@ data Docs' d = FunDoc (FunDoc' d)              | DataDoc (FunDoc' d) -- type constructor docs                        [FunDoc' d] -- data constructor docs-             | ClassDoc Name d   -- class docs-                        [FunDoc' d] -- method docs-                        [(Name, Maybe d)] -- parameters and their docstrings-                        [(Maybe Name, PTerm, (d, [(Name, d)]))] -- instances: name for named instances, the constraint term, the docs-                        [PTerm] -- subclasses-                        [PTerm] -- superclasses-                        (Maybe (FunDoc' d)) -- explicit constructor+             | InterfaceDoc Name d  -- interface docs+                            [FunDoc' d] -- method docs+                            [(Name, Maybe d)] -- parameters and their docstrings+                            [(Maybe Name, PTerm, (d, [(Name, d)]))] -- implementations: name for named implementations, the constraint term, the docs+                            [PTerm] -- sub interfaces+                            [PTerm] -- super interfaces+                            (Maybe (FunDoc' d)) -- explicit constructor              | RecordDoc Name d -- record docs                          (FunDoc' d) -- data constructor docs                          [FunDoc' d] -- projection docs                          [(Name, PTerm, Maybe d)] -- parameters with type and doc-             | NamedInstanceDoc Name (FunDoc' d) -- name is class+             | NamedImplementationDoc Name (FunDoc' d) -- name is interface              | ModDoc [String] -- Module name                       d   deriving Functor@@ -101,8 +101,8 @@         <+> pprintPTerm ppo bnd [] infixes ty         <> showDoc ist d         <> line : showArgs args ((n, False):bnd)-      showArgs ((n, ty, Constraint {}, Just d):args) bnd = -- Class constraints.-            text "Class constraint"+      showArgs ((n, ty, Constraint {}, Just d):args) bnd = -- Interface constraints.+            text "Interface constraint"         <+> pprintPTerm ppo bnd [] infixes ty         <> showDoc ist d         <> line : showArgs args ((n, True):bnd)@@ -139,7 +139,7 @@              if null args then text "No constructors."              else nest 4 (text "Constructors:" <> line <>                           vsep (map (pprintFDWithoutTotality ist False) args))-pprintDocs ist (ClassDoc n doc meths params instances subclasses superclasses ctor)+pprintDocs ist (InterfaceDoc n doc meths params implementations sub_interfaces super_interfaces ctor)            = nest 4 (text "Interface" <+> prettyName True (ppopt_impl ppo) [] n <>                      if nullDocstring doc                        then empty@@ -157,33 +157,33 @@                    ctor              <>              nest 4 (text "Implementations:" <$>-                       vsep (if null instances then [text "<no implementations>"]-                             else map pprintInstance normalInstances))+                       vsep (if null implementations then [text "<no implementations>"]+                             else map pprintImplementation normalImplementations))              <>-             (if null namedInstances then empty+             (if null namedImplementations then empty               else line <$> nest 4 (text "Named implementations:" <$>-                                    vsep (map pprintInstance namedInstances)))+                                    vsep (map pprintImplementation namedImplementations)))              <>-             (if null subclasses then empty+             (if null sub_interfaces then empty               else line <$> nest 4 (text "Child interfaces:" <$>-                                    vsep (map (dumpInstance . prettifySubclasses) subclasses)))+                                    vsep (map (dumpImplementation . prettifySubInterfaces) sub_interfaces)))              <>-             (if null superclasses then empty+             (if null super_interfaces then empty               else line <$> nest 4 (text "Default parent implementations:" <$>-                                     vsep (map dumpInstance superclasses)))+                                     vsep (map dumpImplementation super_interfaces)))   where     params' = zip pNames (repeat False) -    (normalInstances, namedInstances) = partition (\(n, _, _) -> not $ isJust n)-                                                  instances+    (normalImplementations, namedImplementations) = partition (\(n, _, _) -> not $ isJust n)+                                                              implementations      pNames  = map fst params      ppo = ppOptionIst ist     infixes = idris_infixes ist -    pprintInstance (mname, term, (doc, argDocs)) =-      nest 4 (iname mname <> dumpInstance term <>+    pprintImplementation (mname, term, (doc, argDocs)) =+      nest 4 (iname mname <> dumpImplementation term <>               (if nullDocstring doc                   then empty                   else line <>@@ -194,13 +194,13 @@                          doc) <>               if null argDocs                  then empty-                 else line <> vsep (map (prettyInstanceParam (map fst argDocs)) argDocs))+                 else line <> vsep (map (prettyImplementationParam (map fst argDocs)) argDocs))       iname Nothing = empty     iname (Just n) = annName n <+> colon <> space -    prettyInstanceParam params (name, doc) =+    prettyImplementationParam params (name, doc) =       if nullDocstring doc          then empty          else prettyName True False (zip params (repeat False)) name <+>@@ -210,13 +210,13 @@ -- then vsep (map (\(nm,md) -> prettyName True False params' nm <+> maybe empty (showDoc ist) md) params) -- else hsep (punctuate comma (map (prettyName True False params' . fst) params)) -    dumpInstance :: PTerm -> Doc OutputAnnotation-    dumpInstance = pprintPTerm ppo params' [] infixes+    dumpImplementation :: PTerm -> Doc OutputAnnotation+    dumpImplementation = pprintPTerm ppo params' [] infixes -    prettifySubclasses (PPi (Constraint _ _) _ _ tm _)   = prettifySubclasses tm-    prettifySubclasses (PPi plcity           nm fc t1 t2) = PPi plcity (safeHead nm pNames) NoFC (prettifySubclasses t1) (prettifySubclasses t2)-    prettifySubclasses (PApp fc ref args)              = PApp fc ref $ updateArgs pNames args-    prettifySubclasses tm                              = tm+    prettifySubInterfaces (PPi (Constraint _ _) _ _ tm _)    = prettifySubInterfaces tm+    prettifySubInterfaces (PPi plcity           nm fc t1 t2) = PPi plcity (safeHead nm pNames) NoFC (prettifySubInterfaces t1) (prettifySubInterfaces t2)+    prettifySubInterfaces (PApp fc ref args)                 = PApp fc ref $ updateArgs pNames args+    prettifySubInterfaces tm                                 = tm      safeHead _ (y:_) = y     safeHead x []    = x@@ -228,9 +228,9 @@     updateRef nm (PRef fc _ _) = PRef fc [] nm     updateRef _  pt          = pt -    isSubclass (PPi (Constraint _ _) _ _ (PApp _ _ args) (PApp _ (PRef _ _ nm) args')) = nm == n && map getTm args == map getTm args'-    isSubclass (PPi _   _            _ _ pt)                                           = isSubclass pt-    isSubclass _                                                                       = False+    isSubInterface (PPi (Constraint _ _) _ _ (PApp _ _ args) (PApp _ (PRef _ _ nm) args')) = nm == n && map getTm args == map getTm args'+    isSubInterface (PPi _   _            _ _ pt)                                           = isSubInterface pt+    isSubInterface _                                                                       = False      prettyParameters =       if any (isJust . snd) params@@ -264,8 +264,8 @@          else hsep (punctuate comma (map prettyParam [(n,pt) | (n,pt,_) <- params]))     prettyParam (n,pt) = prettyName True False params' n <+> text ":" <+> pprintPTerm ppo params' [] infixes pt -pprintDocs ist (NamedInstanceDoc _cls doc)-   = nest 4 (text "Named instance:" <$> pprintFDWithoutTotality ist True doc)+pprintDocs ist (NamedImplementationDoc _cls doc)+   = nest 4 (text "Named implementation:" <$> pprintFDWithoutTotality ist True doc)  pprintDocs ist (ModDoc mod docs)    = nest 4 $ text "Module" <+> text (concat (intersperse "." mod)) <> colon <$>@@ -287,24 +287,24 @@                              " do not exist! This shouldn't have happened and is a bug." getDocs n w    = do i <- getIState-        docs <- if | Just ci <- lookupCtxtExact n (idris_classes i)-                     -> docClass n ci+        docs <- if | Just ci <- lookupCtxtExact n (idris_interfaces i)+                     -> docInterface n ci                    | Just ri <- lookupCtxtExact n (idris_records i)                      -> docRecord n ri                    | Just ti <- lookupCtxtExact n (idris_datatypes i)                      -> docData n ti-                   | Just class_ <- classNameForInst i n+                   | Just interface_ <- interfaceNameForImpl i n                      -> do fd <- docFun n-                           return $ NamedInstanceDoc class_ fd+                           return $ NamedImplementationDoc interface_ fd                    | otherwise                      -> do fd <- docFun n                            return (FunDoc fd)         return $ fmap (howMuch w) docs-  where classNameForInst :: IState -> Name -> Maybe Name-        classNameForInst ist n =+  where interfaceNameForImpl :: IState -> Name -> Maybe Name+        interfaceNameForImpl ist n =           listToMaybe [ cn-                      | (cn, ci) <- toAlist (idris_classes ist)-                      , n `elem` map fst (class_instances ci)+                      | (cn, ci) <- toAlist (idris_interfaces ist)+                      , n `elem` map fst (interface_implementations ci)                       ]  docData :: Name -> TypeInfo -> Idris Docs@@ -313,44 +313,44 @@        cdocs <- mapM docFun (con_names ti)        return (DataDoc tdoc cdocs) -docClass :: Name -> ClassInfo -> Idris Docs-docClass n ci+docInterface :: Name -> InterfaceInfo -> Idris Docs+docInterface n ci   = do i <- getIState        let docStrings = listToMaybe $ lookupCtxt n $ idris_docstrings i            docstr = maybe emptyDocstring fst docStrings            params = map (\pn -> (pn, docStrings >>= (lookup pn . snd)))-                        (class_params ci)-           docsForInstance inst = fromMaybe (emptyDocstring, []) .+                        (interface_params ci)+           docsForImplementation impl = fromMaybe (emptyDocstring, []) .                                   flip lookupCtxtExact (idris_docstrings i) $-                                  inst-           instances = map (\inst -> (namedInst inst,-                                      delabTy i inst,-                                      docsForInstance inst))-                           (nub (map fst (class_instances ci)))-           (subclasses, instances') = partition (isSubclass . (\(_,tm,_) -> tm)) instances-           superclasses = catMaybes $ map getDInst (class_default_superclasses ci)-       mdocs <- mapM (docFun . fst) (class_methods ci)-       let ctorN = instanceCtorName ci+                                  impl+           implementations = map (\impl -> (namedImpl impl,+                                            delabTy i impl,+                                            docsForImplementation impl))+                             (nub (map fst (interface_implementations ci)))+           (sub_interfaces, implementations') = partition (isSubInterface . (\(_,tm,_) -> tm)) implementations+           super_interfaces = catMaybes $ map getDImpl (interface_default_super_interfaces ci)+       mdocs <- mapM (docFun . fst) (interface_methods ci)+       let ctorN = implementationCtorName ci        ctorDocs <- case basename ctorN of                      SN _ -> return Nothing                      _    -> fmap Just $ docFun ctorN-       return $ ClassDoc+       return $ InterfaceDoc                   n docstr mdocs params-                  instances' (map (\(_,tm,_) -> tm) subclasses) superclasses+                  implementations' (map (\(_,tm,_) -> tm) sub_interfaces) super_interfaces                   ctorDocs   where-    namedInst (NS n ns) = fmap (flip NS ns) (namedInst n)-    namedInst n@(UN _)  = Just n-    namedInst _         = Nothing+    namedImpl (NS n ns) = fmap (flip NS ns) (namedImpl n)+    namedImpl n@(UN _)  = Just n+    namedImpl _         = Nothing -    getDInst (PInstance _ _ _ _ _ _ _ _ _ _ _ _ t _ _) = Just t-    getDInst _                                         = Nothing+    getDImpl (PImplementation _ _ _ _ _ _ _ _ _ _ _ _ t _ _) = Just t+    getDImpl _                                         = Nothing -    isSubclass (PPi (Constraint _ _) _ _ (PApp _ _ args) (PApp _ (PRef _ _ nm) args'))+    isSubInterface (PPi (Constraint _ _) _ _ (PApp _ _ args) (PApp _ (PRef _ _ nm) args'))       = nm == n && map getTm args == map getTm args'-    isSubclass (PPi _ _ _ _ pt)-      = isSubclass pt-    isSubclass _+    isSubInterface (PPi _ _ _ _ pt)+      = isSubInterface pt+    isSubInterface _       = False  docRecord :: Name -> RecordInfo -> Idris Docs
− src/Idris/Elab/Class.hs
@@ -1,368 +0,0 @@-{-|-Module      : Idris.Elab.Class-Description : Code to elaborate interfaces.-Copyright   :-License     : BSD3-Maintainer  : The Idris Community.--}-{-# LANGUAGE PatternGuards #-}-{-# OPTIONS_GHC -fwarn-missing-signatures #-}-module Idris.Elab.Class(elabClass) where--import Idris.AbsSyntax-import Idris.ASTUtils-import Idris.DSL-import Idris.Error-import Idris.Delaborate-import Idris.Imports-import Idris.Elab.Term-import Idris.Coverage-import Idris.DataOpts-import Idris.Providers-import Idris.Primitives-import Idris.Inliner-import Idris.PartialEval-import Idris.DeepSeq-import Idris.Output (iputStrLn, pshow, iWarn, sendHighlighting)-import IRTS.Lang--import Idris.Elab.Type-import Idris.Elab.Data-import Idris.Elab.Utils--import Idris.Core.TT-import Idris.Core.Elaborate hiding (Tactic(..))-import Idris.Core.Evaluate-import Idris.Core.Execute-import Idris.Core.Typecheck-import Idris.Core.CaseTree--import Idris.Docstrings--import Prelude hiding (id, (.))-import Control.Category--import Control.Applicative hiding (Const)-import Control.DeepSeq-import Control.Monad-import Control.Monad.State.Strict as State-import Data.List-import Data.Maybe-import Debug.Trace--import qualified Data.Map as Map-import qualified Data.Set as S-import qualified Data.Text as T-import Data.Char(isLetter, toLower)-import Data.List.Split (splitOn)-import Data.Generics.Uniplate.Data (transform)--import Util.Pretty(pretty, text)--data MArgTy = IA Name | EA Name | CA deriving Show--elabClass :: ElabInfo-          -> SyntaxInfo-          -> Docstring (Either Err PTerm)-          -> FC-          -> [(Name, PTerm)]-          -> Name-          -> FC-          -> [(Name, FC, PTerm)]-          -> [(Name, Docstring (Either Err PTerm))]-          -> [(Name, FC)]                 -- ^ determining params-          -> [PDecl]                      -- ^ class body-          -> Maybe (Name, FC)             -- ^ instance ctor name and location-          -> Docstring (Either Err PTerm) -- ^ instance ctor docs-          -> Idris ()-elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd-    = do let cn = fromMaybe (SN (InstanceCtorN tn)) (fst <$> mcn)-         let tty = pibind (map (\(n, _, ty) -> (n, ty)) ps) (PType fc)-         let constraint = PApp fc (PRef fc [] tn)-                                  (map (pexp . PRef fc []) (map (\(n, _, _) -> n) ps))--         let syn =-              syn_in { using = addToUsing (using syn_in)-                                 [(pn, pt) | (pn, _, pt) <- ps]-                     }--         -- build data declaration-         let mdecls = filter tydecl ds -- method declarations-         let idecls = filter instdecl ds -- default superclass instance declarations-         mapM_ checkDefaultSuperclassInstance idecls-         let mnames = map getMName mdecls-         ist <- getIState-         let constraintNames = nub $-                 concatMap (namesIn [] ist) (map snd constraints)--         mapM_ (checkConstraintName (map (\(x, _, _) -> x) ps)) constraintNames--         logElab 2 $ "Building methods " ++ show mnames-         ims <- mapM (tdecl mnames) mdecls-         defs <- mapM (defdecl (map (\ (x,y,z) -> z) ims) constraint)-                      (filter clause ds)-         let (methods, imethods)-              = unzip (map (\ (x, y, z) -> (x, y)) ims)-         let defaults = map (\ (x, (y, z)) -> (x,y)) defs--         -- build instance constructor type-         let cty = impbind [(pn, pt) | (pn, _, pt) <- ps] $ conbind constraints-                      $ pibind (map (\ (n, ty) -> (nsroot n, ty)) methods)-                               constraint--         let cons = [(cd, pDocs ++ mapMaybe memberDocs ds, cn, NoFC, cty, fc, [])]-         let ddecl = PDatadecl tn NoFC tty cons--         logElab 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)--         -- Elaborate the data declaration-         elabData info (syn { no_imp = no_imp syn ++ mnames,-                              imp_methods = mnames }) doc pDocs fc [] ddecl-         dets <- findDets cn (map fst fds)-         addClass tn (CI cn (map nodoc imethods) defaults idecls (map (\(n, _, _) -> n) ps) [] dets)--         -- for each constraint, build a top level function to chase it-         cfns <- mapM (cfun cn constraint syn (map fst imethods)) constraints-         mapM_ (rec_elabDecl info EAll info) (concat cfns)--         -- for each method, build a top level function-         fns <- mapM (tfun cn constraint (syn { imp_methods = mnames })-                           (map fst imethods)) imethods-         logElab 5 $ "Functions " ++ show fns-         -- Elaborate the the top level methods-         mapM_ (rec_elabDecl info EAll info) (concat fns)--         -- Flag all the top level data declarations as injective-         mapM_ (\n -> do setInjectivity n True-                         addIBC (IBCInjective n True))-               (map fst (filter (\(_, (inj, _, _, _, _)) -> inj) imethods))--         -- add the default definitions-         mapM_ (rec_elabDecl info EAll info) (concatMap (snd.snd) defs)-         addIBC (IBCClass tn)--         sendHighlighting $-           [(tnfc, AnnName tn Nothing Nothing Nothing)] ++-           [(pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] ++-           [(fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] ++-           maybe [] (\(conN, conNFC) -> [(conNFC, AnnName conN Nothing Nothing Nothing)]) mcn--  where-    nodoc (n, (inj, _, _, o, t)) = (n, (inj, o, t))--    pibind [] x = x-    pibind ((n, ty): ns) x = PPi expl n NoFC ty (pibind ns (chkUniq ty x))--    -- To make sure the type constructor of the class is in the appropriate-    -- uniqueness hierarchy-    chkUniq u@(PUniverse _) (PType _) = u-    chkUniq (PUniverse l) (PUniverse r) = PUniverse (min l r)-    chkUniq (PPi _ _ _ _ sc) t = chkUniq sc t-    chkUniq _ t = t--    -- TODO: probably should normalise-    checkDefaultSuperclassInstance :: PDecl -> Idris ()-    checkDefaultSuperclassInstance (PInstance _ _ _ fc cs _ _ _ n _ ps _ _ _ _)-        = do when (not $ null cs) . tclift-                $ tfail (At fc (Msg "Default superclass instances can't have constraints."))-             i <- getIState-             let t = PApp fc (PRef fc [] n) (map pexp ps)-             let isConstrained = any (== t) (map snd constraints)-             when (not isConstrained) . tclift-                $ tfail (At fc (Msg "Default instances must be for a superclass constraint on the containing class."))-             return ()--    checkConstraintName :: [Name] -> Name -> Idris ()-    checkConstraintName bound cname-        | cname `notElem` bound-            = tclift $ tfail (At fc (Msg $ "Name " ++ show cname ++-                         " is not bound in interface " ++ show tn-                         ++ " " ++ showSep " " (map show bound)))-        | otherwise = return ()--    impbind :: [(Name, PTerm)] -> PTerm -> PTerm-    impbind [] x = x-    impbind ((n, ty): ns) x = PPi impl n NoFC ty (impbind ns x)--    conbind :: [(Name, PTerm)] -> PTerm -> PTerm-    conbind ((c, ty) : ns) x = PPi constraint c NoFC ty (conbind ns x)-    conbind [] x = x--    getMName (PTy _ _ _ _ _ n nfc _) = nsroot n-    getMName (PData _ _ _ _ _ (PLaterdecl n nfc _)) = nsroot n--    tdecl allmeths (PTy doc _ syn _ o n nfc t)-           = do t' <- implicit' info syn (map (\(n, _, _) -> n) ps ++ allmeths) n t-                logElab 2 $ "Method " ++ show n ++ " : " ++ showTmImpls t'-                return ( (n, (toExp (map (\(pn, _, _) -> pn) ps) Exp t')),-                         (n, (False, nfc, doc, o, (toExp (map (\(pn, _, _) -> pn) ps)-                                              (\ l s p -> Imp l s p Nothing True) t'))),-                         (n, (nfc, syn, o, t) ) )-    tdecl allmeths (PData doc _ syn _ _ (PLaterdecl n nfc t))-           = do let o = []-                t' <- implicit' info syn (map (\(n, _, _) -> n) ps ++ allmeths) n t-                logElab 2 $ "Data method " ++ show n ++ " : " ++ showTmImpls t'-                return ( (n, (toExp (map (\(pn, _, _) -> pn) ps) Exp t')),-                         (n, (True, nfc, doc, o, (toExp (map (\(pn, _, _) -> pn) ps)-                                              (\ l s p -> Imp l s p Nothing True) t'))),-                         (n, (nfc, syn, o, t) ) )-    tdecl allmeths (PData doc _ syn _ _ _)-         = ierror $ At fc (Msg "Data definitions not allowed in a class declaration")-    tdecl _ _ = ierror $ At fc (Msg "Not allowed in a class declaration")--    -- Create default definitions-    defdecl mtys c d@(PClauses fc opts n cs) =-        case lookup n mtys of-            Just (nfc, syn, o, ty) ->-              do let ty' = insertConstraint c (map fst mtys) ty-                 let ds = map (decorateid defaultdec)-                              [PTy emptyDocstring [] syn fc [] n nfc ty',-                               PClauses fc (o ++ opts) n cs]-                 logElab 1 (show ds)-                 return (n, ((defaultdec n, ds!!1), ds))-            _ -> ierror $ At fc (Msg (show n ++ " is not a method"))-    defdecl _ _ _ = ifail "Can't happen (defdecl)"--    defaultdec (UN n) = sUN ("default#" ++ str n)-    defaultdec (NS n ns) = NS (defaultdec n) ns--    tydecl (PTy{}) = True-    tydecl (PData _ _ _ _ _ _) = True-    tydecl _ = False-    instdecl (PInstance{}) = True-    instdecl _ = False-    clause (PClauses{}) = True-    clause _ = False--    -- Generate a function for chasing a dictionary constraint-    cfun :: Name -> PTerm -> SyntaxInfo -> [a] -> (Name, PTerm) -> Idris [PDecl' PTerm]-    cfun cn c syn all (cnm, con)-        = do let cfn = SN (ParentN cn (txt (show con)))-             let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]-             let capp = PApp fc (PRef fc [] cn) (map (pexp . PRef fc []) mnames)-             let lhs = PApp fc (PRef fc [] cfn) [pconst capp]-             let rhs = PResolveTC (fileFC "HACK")-             let ty = PPi constraint cnm NoFC c con-             logElab 2 ("Dictionary constraint: " ++ showTmImpls ty)-             logElab 2 (showTmImpls lhs ++ " = " ++ showTmImpls rhs)-             i <- getIState-             let conn = case con of-                            PRef _ _ n -> n-                            PApp _ (PRef _ _ n) _ -> n-             let conn' = case lookupCtxtName conn (idris_classes i) of-                                [(n, _)] -> n-                                _ -> conn-             addInstance False True conn' cfn-             addIBC (IBCInstance False True conn' cfn)---              iputStrLn ("Added " ++ show (conn, cfn, ty))-             return [PTy emptyDocstring [] syn fc [] cfn NoFC ty,-                     PClauses fc [Inlinable, Dictionary] cfn [PClause fc cfn lhs [] rhs []]]--    -- | Generate a top level function which looks up a method in a given-    -- dictionary (this is inlinable, always)-    tfun :: Name -- ^ The name of the class-         -> PTerm -- ^ A constraint for the class, to be inserted under the implicit bindings-         -> SyntaxInfo -> [Name] -- ^ All the method names-         -> (Name, (Bool, FC, Docstring (Either Err PTerm), FnOpts, PTerm))-            -- ^ The present declaration-         -> Idris [PDecl]-    tfun cn c syn all (m, (isdata, mfc, doc, o, ty))-        = do let ty' = expandMethNS syn (insertConstraint c all ty)-             let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]-             let capp = PApp fc (PRef fc [] cn) (map (pexp . PRef fc []) mnames)-             let margs = getMArgs ty-             let anames = map (\x -> sMN x "arg") [0..]-             let lhs = PApp fc (PRef fc [] m) (pconst capp : lhsArgs margs anames)-             let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)-             logElab 2 ("Top level type: " ++ showTmImpls ty')-             logElab 1 (show (m, ty', capp, margs))-             logElab 2 ("Definition: " ++ showTmImpls lhs ++ " = " ++ showTmImpls rhs)-             return [PTy doc [] syn fc o m mfc ty',-                     PClauses fc [Inlinable] m [PClause fc m lhs [] rhs []]]--    getMArgs (PPi (Imp _ _ _ _ _) n _ ty sc) = IA n : getMArgs sc-    getMArgs (PPi (Exp _ _ _) n _ ty sc) = EA n : getMArgs sc-    getMArgs (PPi (Constraint _ _) n _ ty sc) = CA : getMArgs sc-    getMArgs _ = []--    getMeth :: [Name] -> [Name] -> Name -> PTerm-    getMeth (m:ms) (a:as) x | x == a = PRef fc [] m-                            | otherwise = getMeth ms as x--    lhsArgs (EA _ : xs) (n : ns) = [] -- pexp (PRef fc n) : lhsArgs xs ns-    lhsArgs (IA n : xs) ns = pimp n (PRef fc [] n) False : lhsArgs xs ns-    lhsArgs (CA : xs) ns = lhsArgs xs ns-    lhsArgs [] _ = []--    rhsArgs (EA _ : xs) (n : ns) = [] -- pexp (PRef fc n) : rhsArgs xs ns-    rhsArgs (IA n : xs) ns = pexp (PRef fc [] n) : rhsArgs xs ns-    rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns-    rhsArgs [] _ = []--    -- Add the top level constraint. Put it first - elaboration will resolve-    -- the order of the implicits if there are dependencies.-    -- Also ensure the dictionary is used for lookup of any methods that-    -- are used in the type-    insertConstraint :: PTerm -> [Name] -> PTerm -> PTerm-    insertConstraint c all sc-          = let dictN = sMN 0 "__class" in-                PPi (constraint { pstatic = Static })-                    dictN NoFC c-                    (constrainMeths (map basename all)-                                    dictN sc)-     where-       -- After we insert the constraint into the lookup, we need to-       -- ensure that the same dictionary is used to resolve lookups-       -- to the other methods in the class-       constrainMeths :: [Name] -> Name -> PTerm -> PTerm-       constrainMeths allM dictN tm = transform (addC allM dictN) tm--       addC allM dictN m@(PRef fc hls n)-          | n `elem` allM = PApp NoFC m [pconst (PRef NoFC hls dictN)]-          | otherwise = m-       addC _ _ tm = tm--    -- make arguments explicit and don't bind class parameters-    toExp ns e (PPi (Imp l s p _ _) n fc ty sc)-        | n `elem` ns = toExp ns e sc-        | otherwise = PPi (e l s p) n fc ty (toExp ns e sc)-    toExp ns e (PPi p n fc ty sc) = PPi p n fc ty (toExp ns e sc)-    toExp ns e sc = sc---- | Get the method declaration name corresponding to a user-provided name-mdec :: Name -> Name-mdec (UN n) = SN (MethodN (UN n))-mdec (NS x n) = NS (mdec x) n-mdec x = x---- | Get the docstring corresponding to a member, if one exists-memberDocs :: PDecl -> Maybe (Name, Docstring (Either Err PTerm))-memberDocs (PTy d _ _ _ _ n _ _) = Just (basename n, d)-memberDocs (PPostulate _ d _ _ _ _ n _) = Just (basename n, d)-memberDocs (PData d _ _ _ _ pdata) = Just (basename $ d_name pdata, d)-memberDocs (PRecord d _ _ _ n _ _ _ _ _ _ _ ) = Just (basename n, d)-memberDocs (PClass d _ _ _ n _ _ _ _ _ _ _) = Just (basename n, d)-memberDocs _ = Nothing----- | In a top level type for a method, expand all the method names' namespaces--- so that we don't have to disambiguate later-expandMethNS :: SyntaxInfo-                -> PTerm -> PTerm-expandMethNS syn = mapPT expand-  where-    expand (PRef fc hls n) | n `elem` imp_methods syn = PRef fc hls $ expandNS syn n-    expand t = t---- | Find the determining parameter locations-findDets :: Name -> [Name] -> Idris [Int]-findDets n ns =-    do i <- getIState-       return $ case lookupTyExact n (tt_ctxt i) of-            Just ty -> getDetPos 0 ns ty-            Nothing -> []-  where-    getDetPos i ns (Bind n (Pi _ _ _) sc)-       | n `elem` ns = i : getDetPos (i + 1) ns sc-       | otherwise = getDetPos (i + 1) ns sc-    getDetPos _ _ _ = []
src/Idris/Elab/Clause.hs view
@@ -51,6 +51,8 @@ import qualified Control.Monad.State.Lazy as LState import Data.List import Data.Maybe+import Data.Word+ import Debug.Trace  import qualified Data.Map as Map@@ -395,12 +397,15 @@                                   [Total _] -> 65536                                   [Productive] -> 16                                   _ -> 1+                let specnames = mapMaybe (specName (pe_simple specdecl))+                                         (snd specapp)+                descs <- mapM getStaticsFrom (map fst specnames)+                 let opts = [Specialise ((if pe_simple specdecl                                             then map (\x -> (x, Nothing)) cgns'                                             else []) ++-                                         (n, Just maxred) :-                                           mapMaybe (specName (pe_simple specdecl))-                                                    (snd specapp))]+                                         (n, Just maxred) : specnames ++ +                                             concat descs)]                 logElab 3 $ "Specialising application: " ++ show specapp                               ++ " in " ++ show caller ++                               " with " ++ show opts@@ -441,6 +446,20 @@         | (P Ref n _, _) <- unApply tm = Just (n, Just (if simpl then 1 else 0))     specName simpl _ = Nothing +    -- get the descendants of the name 'n' which are marked %static+    -- Marking a function %static essentially means it's used to construct+    -- programs, so should be evaluated by the partial evaluator+    getStaticsFrom :: Name -> Idris [(Name, Maybe Int)]+    getStaticsFrom n = do ns <- getAllNames n+                          i <- getIState+                          let statics = filter (staticFn i) ns+                          return (map (\n -> (n, Nothing)) statics)+        +    staticFn :: IState -> Name -> Bool+    staticFn i n =  case lookupCtxt n (idris_flags i) of+                            [opts] -> elem StaticFn opts+                            _ -> False+     notStatic ist n = case lookupCtxtExact n (idris_statics ist) of                            Just s -> not (or s)                            _ -> True@@ -487,9 +506,9 @@              -- Simple but effective string hashing...             -- Keep it to 32 bits for readability/debuggability-            qhash :: Int -> String -> String+            qhash :: Word64 -> String -> String             qhash hash [] = showHex (abs hash `mod` 0xffffffff) ""-            qhash hash (x:xs) = qhash (hash * 33 + fromEnum x) xs+            qhash hash (x:xs) = qhash (hash * 33 + fromIntegral(fromEnum x)) xs  -- | Checks if the clause is a possible left hand side. checkPossible :: ElabInfo -> FC -> Bool -> Name -> PTerm -> Idris Bool@@ -647,7 +666,7 @@          let winfo = (pinfo info newargs defs windex) { elabFC = Just fc }         let wb = map (mkStatic static_names) $-                 map (expandInstanceScope ist decorate newargs defs) $+                 map (expandImplementationScope ist decorate newargs defs) $                  map (expandParamsD False ist decorate newargs defs) whereblock          -- Split the where block into declarations with a type, and those@@ -1090,15 +1109,15 @@          addResolves ty (PApp fc f args) = PApp fc f (addResolvesArgs fc ty args)          addResolves ty tm = tm -         -- if an argument's type is a type class, and is otherwise to-         -- be inferred, then resolve it with instance search+         -- if an argument's type is an interface, and is otherwise to+         -- be inferred, then resolve it with implementation search          -- This is something of a hack, because matching on the top level          -- application won't find this information for us          addResolvesArgs :: FC -> Term -> [PArg] -> [PArg]          addResolvesArgs fc (Bind n (Pi _ ty _) sc) (a : args)              | (P _ cn _, _) <- unApply ty,                getTm a == Placeholder-                 = case lookupCtxtExact cn (idris_classes ist) of+                 = case lookupCtxtExact cn (idris_interfaces ist) of                         Just _ -> a { getTm = PResolveTC fc } : addResolvesArgs fc sc args                         Nothing -> a : addResolvesArgs fc sc args          addResolvesArgs fc (Bind n (Pi _ ty _) sc) (a : args)
+ src/Idris/Elab/Implementation.hs view
@@ -0,0 +1,502 @@+{-|+Module      : Idris.Elab.Implementation+Description : Code to elaborate instances.+Copyright   :+License     : BSD3+Maintainer  : The Idris Community.+-}+{-# LANGUAGE PatternGuards #-}+module Idris.Elab.Implementation(elabImplementation) where++import Idris.AbsSyntax+import Idris.ASTUtils+import Idris.DSL+import Idris.Error+import Idris.Delaborate+import Idris.Imports+import Idris.Coverage+import Idris.DataOpts+import Idris.Providers+import Idris.Primitives+import Idris.Inliner+import Idris.PartialEval+import Idris.DeepSeq+import Idris.Output (iputStrLn, pshow, iWarn, sendHighlighting)+import IRTS.Lang++import Idris.Elab.Type+import Idris.Elab.Data+import Idris.Elab.Utils+import Idris.Elab.Term++import Idris.Core.TT+import Idris.Core.Elaborate hiding (Tactic(..))+import Idris.Core.Evaluate+import Idris.Core.Execute+import Idris.Core.Typecheck+import Idris.Core.CaseTree++import Idris.Docstrings++import Prelude hiding (id, (.))+import Control.Category++import Control.Applicative hiding (Const)+import Control.DeepSeq+import Control.Monad+import Control.Monad.State.Strict as State+import Data.List+import Data.Maybe+import Debug.Trace++import qualified Data.Map as Map+import qualified Data.Set as S+import qualified Data.Text as T+import Data.Char(isLetter, toLower)+import Data.List.Split (splitOn)++import Util.Pretty(pretty, text)++elabImplementation :: ElabInfo+                   -> SyntaxInfo+                   -> Docstring (Either Err PTerm)+                   -> [(Name, Docstring (Either Err PTerm))]+                   -> ElabWhat        -- ^ phase+                   -> FC+                   -> [(Name, PTerm)] -- ^ constraints+                   -> [Name]          -- ^ parent dictionary names (optionally)+                   -> Accessibility+                   -> FnOpts+                   -> Name            -- ^ the interface+                   -> FC              -- ^ precise location of interface name+                   -> [PTerm]         -- ^ interface parameters (i.e. implementation)+                   -> [(Name, PTerm)] -- ^ Extra arguments in scope (e.g. implementation in where block)+                   -> PTerm           -- ^ full implementation type+                   -> Maybe Name      -- ^ explicit name+                   -> [PDecl]+                   -> Idris ()+elabImplementation info syn doc argDocs what fc cs parents acc opts n nfc ps pextra t expn ds = do+    ist <- getIState+    (n, ci) <- case lookupCtxtName n (idris_interfaces ist) of+                  [c] -> return c+                  [] -> ifail $ show fc ++ ":" ++ show n ++ " is not an interface"+                  cs -> tclift $ tfail $ At fc+                           (CantResolveAlts (map fst cs))+    let constraint = PApp fc (PRef fc [] n) (map pexp ps)+    let iname = mkiname n (namespace info) ps expn+    putIState (ist { hide_list = addDef iname acc (hide_list ist) })+    ist <- getIState++    let totopts = Dictionary : Inlinable : opts++    let emptyinterface = null (interface_methods ci)+    when (what /= EDefns) $ do+         nty <- elabType' True info syn doc argDocs fc totopts iname NoFC+                          (piBindp expl_param pextra t)+         -- if the implementation type matches any of the implementations we have already,+         -- and it's not a named implementation, then it's overlapping, so report an error+         case expn of+            Nothing -> do mapM_ (maybe (return ()) overlapping . findOverlapping ist (interface_determiners ci) (delab ist nty))+                                (map fst $ interface_implementations ci)+                          addImplementation intImpl True n iname+            Just _ -> addImplementation intImpl False n iname+    when (what /= ETypes && (not (null ds && not emptyinterface))) $ do+         -- Add the parent implementation names to the privileged set+         oldOpen <- addOpenImpl parents++         let ips = zip (interface_params ci) ps+         let ns = case n of+                    NS n ns' -> ns'+                    _ -> []+         -- get the implicit parameters that need passing through to the+         -- where block+         wparams <- mapM (\p -> case p of+                                  PApp _ _ args -> getWParams (map getTm args)+                                  a@(PRef fc _ f) -> getWParams [a]+                                  _ -> return []) ps+         ist <- getIState+         let pnames = nub $ map pname (concat (nub wparams)) +++                          concatMap (namesIn [] ist) ps++         let superInterfaceImplementations = map (substImplementation ips pnames) (interface_default_super_interfaces ci)+         undefinedSuperInterfaceImplementations <- filterM (fmap not . isOverlapping ist) superInterfaceImplementations+         mapM_ (rec_elabDecl info EAll info) undefinedSuperInterfaceImplementations++         ist <- getIState+         -- Bring variables in implementation head into scope when building the+         -- dictionary+         let headVars = nub $ concatMap getHeadVars ps+         let (headVarTypes, ty)+                = case lookupTyExact iname (tt_ctxt ist) of+                              Just ty -> (map (\n -> (n, getTypeIn ist n ty)) headVars, ty)+                              _ -> (zip headVars (repeat Placeholder), Erased)+         logElab 3 $ "Head var types " ++ show headVarTypes ++ " from " ++ show ty++         let all_meths = map (nsroot . fst) (interface_methods ci)+         let mtys = map (\ (n, (inj, op, t)) ->+                   let t_in = substMatchesShadow ips pnames t+                       mnamemap =+                          map (\n -> (n, PApp fc (PRef fc [] (decorate ns iname n))+                                              (map (toImp fc) headVars)))+                                      all_meths+                       t' = substMatchesShadow mnamemap pnames t_in in+                       (decorate ns iname n,+                           op, coninsert cs pextra t', t'))+              (interface_methods ci)+         logElab 3 (show (mtys, ips))+         logElab 5 ("Before defaults: " ++ show ds ++ "\n" ++ show (map fst (interface_methods ci)))+         let ds_defs = insertDefaults ist iname (interface_defaults ci) ns ds+         logElab 3 ("After defaults: " ++ show ds_defs ++ "\n")+         let ds' = reorderDefs (map fst (interface_methods ci)) ds_defs+         logElab 1 ("Reordered: " ++ show ds' ++ "\n")++         mapM_ (warnMissing ds' ns iname) (map fst (interface_methods ci))+         mapM_ (checkInInterface (map fst (interface_methods ci))) (concatMap defined ds')+         let wbTys = map mkTyDecl mtys+         let wbVals_orig = map (decorateid (decorate ns iname)) ds'+         ist <- getIState+         let wbVals = map (expandParamsD False ist id pextra (map methName mtys)) wbVals_orig+         let wb = wbTys ++ wbVals++         logElab 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)+         logElab 3 $ "Implementation is " ++ show ps ++ " implicits " ++ show (concat (nub wparams))++         let lhsImps = map (\n -> pimp n (PRef fc [] n) True) headVars++         let lhs = PApp fc (PRef fc [] iname) (lhsImps ++ map (toExp .fst) pextra)+         let rhs = PApp fc (PRef fc [] (implementationCtorName ci))+                           (map (pexp . (mkMethApp lhsImps)) mtys)++         logElab 5 $ "Implementation LHS " ++ show totopts ++ "\n" ++ showTmImpls lhs ++ " " ++ show headVars+         logElab 5 $ "Implementation RHS " ++ show rhs++         push_estack iname True+         logElab 3 ("Method types: " ++ show wbTys)+         logElab 3 ("Method bodies (before params): " ++ show wbVals_orig)+         logElab 3 ("Method bodies: " ++ show wbVals)++         let idecls = [PClauses fc totopts iname+                              [PClause fc iname lhs [] rhs []]]++         mapM_ (rec_elabDecl info EAll info) (map (impBind headVarTypes) wbTys)+         mapM_ (rec_elabDecl info EAll info) idecls++         ctxt <- getContext+         let ifn_ty = case lookupTyExact iname ctxt of+                           Just t -> t+                           Nothing -> error "Can't happen (interface constructor)"+         let ifn_is = case lookupCtxtExact iname (idris_implicits ist) of+                           Just t -> t+                           Nothing -> []+         let prop_params = getParamsInType ist [] ifn_is ifn_ty++         logElab 3 $ "Propagating parameters to methods: "+                           ++ show (iname, prop_params)++         let wbVals' = map (addParams prop_params) wbVals++         mapM_ (rec_elabDecl info EAll info) wbVals'++         mapM_ (checkInjectiveDef fc (interface_methods ci)) (zip ds' wbVals')++         pop_estack++         setOpenImpl oldOpen+--          totalityCheckBlock++         checkInjectiveArgs fc n (interface_determiners ci) (lookupTyExact iname (tt_ctxt ist))+         addIBC (IBCImplementation intImpl (isNothing expn) n iname)++  where+    intImpl = case ps of+                [PConstant NoFC (AType (ATInt ITNative))] -> True+                _ -> False++    mkiname n' ns ps' expn' =+        case expn' of+          Nothing -> case ns of+                          [] -> SN (sImplementationN n' (map show ps'))+                          m -> sNS (SN (sImplementationN n' (map show ps'))) m+          Just nm -> nm++    substImplementation ips pnames (PImplementation doc argDocs syn _ cs parents acc opts n nfc ps pextra t expn ds)+        = PImplementation doc argDocs syn fc cs parents acc opts n nfc+                     (map (substMatchesShadow ips pnames) ps)+                     pextra+                     (substMatchesShadow ips pnames t) expn ds++    isOverlapping i (PImplementation doc argDocs syn _ _ _ _ _ n nfc ps pextra t expn _)+        = case lookupCtxtName n (idris_interfaces i) of+            [(n, ci)] -> let iname = (mkiname n (namespace info) ps expn) in+                            case lookupTy iname (tt_ctxt i) of+                              [] -> elabFindOverlapping i ci iname syn t+                              (_:_) -> return True+            _ -> return False -- couldn't find interface, just let elabImplementation fail later++    -- TODO: largely based upon elabType' - should try to abstract+    -- Issue #1614 in the issue tracker:+    --    https://github.com/idris-lang/Idris-dev/issues/1614+    elabFindOverlapping i ci iname syn t+        = do ty' <- addUsingConstraints syn fc t+             -- TODO think: something more in info?+             ty' <- implicit info syn iname ty'+             let ty = addImpl [] i ty'+             ctxt <- getContext+             (ElabResult tyT _ _ ctxt' newDecls highlights newGName, _) <-+                tclift $ elaborate (constraintNS info) ctxt (idris_datatypes i) (idris_name i) iname (TType (UVal 0)) initEState+                         (errAt "type of " iname Nothing (erun fc (build i info ERHS [] iname ty)))+             setContext ctxt'+             processTacticDecls info newDecls+             sendHighlighting highlights+             updateIState $ \i -> i { idris_name = newGName }++             ctxt <- getContext+             (cty, _) <- recheckC (constraintNS info) fc id [] tyT+             let nty = normalise ctxt [] cty+             return $ any (isJust . findOverlapping i (interface_determiners ci) (delab i nty)) (map fst $ interface_implementations ci)++    findOverlapping i dets t n+     | SN (ParentN _ _) <- n = Nothing+     | otherwise+        = case lookupTy n (tt_ctxt i) of+            [t'] -> let tret = getRetType t+                        tret' = getRetType (delab i t') in+                        case matchArgs i dets tret' tret of+                           Right _ -> Just tret'+                           Left _ -> case matchArgs i dets tret tret' of+                                       Right _ -> Just tret'+                                       Left _ -> Nothing+            _ -> Nothing+    overlapping t' = tclift $ tfail (At fc (Msg $+                          "Overlapping implementation: " ++ show t' ++ " already defined"))+    getRetType (PPi _ _ _ _ sc) = getRetType sc+    getRetType t = t++    matchArgs i dets x y =+        let x' = keepDets dets x+            y' = keepDets dets y in+            matchClause i x' y'++    keepDets dets (PApp fc f args)+        = PApp fc f $ let a' = zip [0..] args in+              map snd (filter (\(i, _) -> i `elem` dets) a')+    keepDets dets t = t++    methName (n, _, _, _) = n+    toExp n = pexp (PRef fc [] n)++    mkMethApp ps (n, _, _, ty)+              = lamBind 0 ty (papp fc (PRef fc [] n)+                     (ps ++ map (toExp . fst) pextra ++ methArgs 0 ty))+       where+          needed is p = pname p `elem` map pname is++    lamBind i (PPi (Constraint _ _) _ _ _ sc) sc'+          = PLam fc (sMN i "meth") NoFC Placeholder (lamBind (i+1) sc sc')+    lamBind i (PPi _ n _ ty sc) sc'+          = PLam fc (sMN i "meth") NoFC Placeholder (lamBind (i+1) sc sc')+    lamBind i _ sc = sc+    methArgs i (PPi (Imp _ _ _ _ _) n _ ty sc)+        = PImp 0 True [] n (PRef fc [] (sMN i "meth")) : methArgs (i+1) sc+    methArgs i (PPi (Exp _ _ _) n _ ty sc)+        = PExp 0 [] (sMN 0 "marg") (PRef fc [] (sMN i "meth")) : methArgs (i+1) sc+    methArgs i (PPi (Constraint _ _) n _ ty sc)+        = PConstraint 0 [] (sMN 0 "marg") (PResolveTC fc) : methArgs (i+1) sc+    methArgs i _ = []++    papp fc f [] = f+    papp fc f as = PApp fc f as++    getWParams [] = return []+    getWParams (p : ps)+      | PRef _ _ n <- p+        = do ps' <- getWParams ps+             ctxt <- getContext+             case lookupP n ctxt of+                [] -> return (pimp n (PRef fc [] n) True : ps')+                _ -> return ps'+    getWParams (_ : ps) = getWParams ps++    decorate ns iname (NS (UN nm) s)+         = NS (SN (WhereN 0 iname (SN (MethodN (UN nm))))) ns+    decorate ns iname nm+         = NS (SN (WhereN 0 iname (SN (MethodN nm)))) ns++    mkTyDecl (n, op, t, _)+        = PTy emptyDocstring [] syn fc op n NoFC+               (mkUniqueNames [] [] t)++    conbind :: [(Name, PTerm)] -> PTerm -> PTerm+    conbind ((c,ty) : ns) x = PPi constraint c NoFC ty (conbind ns x)+    conbind [] x = x++    extrabind :: [(Name, PTerm)] -> PTerm -> PTerm+    extrabind ((c,ty) : ns) x = PPi expl c NoFC ty (extrabind ns x)+    extrabind [] x = x++    coninsert :: [(Name, PTerm)] -> [(Name, PTerm)] -> PTerm -> PTerm+    coninsert cs ex (PPi p@(Imp _ _ _ _ _) n fc t sc) = PPi p n fc t (coninsert cs ex sc)+    coninsert cs ex sc = conbind cs (extrabind ex sc)++    -- Reorder declarations to be in the same order as defined in the+    -- interface declaration (important so that we insert default definitions+    -- in the right place, and so that dependencies between methods are+    -- respected)+    reorderDefs :: [Name] -> [PDecl] -> [PDecl]+    reorderDefs ns [] = []+    reorderDefs [] ds = ds+    reorderDefs (n : ns) ds = case pick n [] ds of+                                  Just (def, ds') -> def : reorderDefs ns ds'+                                  Nothing -> reorderDefs ns ds++    pick n acc [] = Nothing+    pick n acc (def@(PClauses _ _ cn cs) : ds)+         | nsroot n == nsroot cn = Just (def, acc ++ ds)+    pick n acc (d : ds) = pick n (acc ++ [d]) ds++    insertDefaults :: IState -> Name ->+                      [(Name, (Name, PDecl))] -> [T.Text] ->+                      [PDecl] -> [PDecl]+    insertDefaults i iname [] ns ds = ds+    insertDefaults i iname ((n,(dn, clauses)) : defs) ns ds+       = insertDefaults i iname defs ns (insertDef i n dn clauses ns iname ds)++    insertDef i meth def clauses ns iname decls+        | not $ any (clauseFor meth iname ns) decls+            = let newd = expandParamsD False i (\n -> meth) [] [def] clauses in+                  -- trace (show newd) $+                  decls ++ [newd]+        | otherwise = decls++    warnMissing decls ns iname meth+        | not $ any (clauseFor meth iname ns) decls+            = iWarn fc . text $ "method " ++ show meth ++ " not defined"+        | otherwise = return ()++    checkInInterface ns meth+        | any (eqRoot meth) ns = return ()+        | otherwise = tclift $ tfail (At fc (Msg $+                                show meth ++ " not a method of interface " ++ show n))++    eqRoot x y = nsroot x == nsroot y++    clauseFor m iname ns (PClauses _ _ m' _)+       = decorate ns iname m == decorate ns iname m'+    clauseFor m iname ns _ = False++getHeadVars :: PTerm -> [Name]+getHeadVars (PRef _ _ n) | implicitable n = [n]+getHeadVars (PApp _ _ args) = concatMap getHeadVars (map getTm args)+getHeadVars (PPair _ _ _ l r) = getHeadVars l ++ getHeadVars r+getHeadVars (PDPair _ _ _ l t r) = getHeadVars l ++ getHeadVars t ++ getHeadVars t+getHeadVars _ = []++-- | Implicitly bind variables from the implementation head in method types+impBind :: [(Name, PTerm)] -> PDecl -> PDecl+impBind vs (PTy d ds syn fc opts n fc' t)+     = PTy d ds syn fc opts n fc'+          (doImpBind (filter (\(n, ty) -> n `notElem` boundIn t) vs) t)+  where+    doImpBind [] ty = ty+    doImpBind ((n, argty) : ns) ty+       = PPi impl n NoFC argty (doImpBind ns ty)++    boundIn (PPi _ n _ _ sc) = n : boundIn sc+    boundIn _ = []++getTypeIn :: IState -> Name -> Type -> PTerm+getTypeIn ist n (Bind x b sc)+    | n == x = delab ist (binderTy b)+    | otherwise = getTypeIn ist n (substV (P Ref x Erased) sc)+getTypeIn ist n tm = Placeholder++toImp fc n = pimp n (PRef fc [] n) True++-- | Propagate interface parameters to method bodies, if they're not+-- already there, and they are needed (i.e. appear in method's type)+addParams :: [Name] -> PDecl -> PDecl+addParams ps (PClauses fc opts n cs) = PClauses fc opts n (map addCParams cs)+  where+    addCParams (PClause fc n lhs ws rhs wb)+        = PClause fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws rhs wb+    addCParams (PWith fc n lhs ws sc pn ds)+        = PWith fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws sc pn+                      (map (addParams ps) ds)+    addCParams c = c++    addTmParams ps (PRef fc hls n)+        = PApp fc (PRef fc hls n) (map (toImp fc) ps)+    addTmParams ps (PApp fc ap@(PRef fc' hls n) args)+        = PApp fc ap (mergePs (map (toImp fc) ps) args)+    addTmParams ps tm = tm++    mergePs [] args = args+    mergePs (p : ps) args+         | isImplicit p,+           pname p `notElem` map pname args+               = p : mergePs ps args+       where+         isImplicit (PExp{}) = False+         isImplicit _ = True+    mergePs (p : ps) args+         = mergePs ps args++    -- Don't propagate a parameter if the name is rebound explicitly+    dropPs :: [Name] -> [Name] -> [Name]+    dropPs ns = filter (\x -> x `notElem` ns)++addParams ps d = d++-- | Check a given method definition is injective, if the interface info+-- says it needs to be.  Takes originally written decl and the one+-- with name decoration, so we know which name to look up.+checkInjectiveDef :: FC -> [(Name, (Bool, FnOpts, PTerm))] ->+                           (PDecl, PDecl) -> Idris ()+checkInjectiveDef fc ns (PClauses _ _ n cs, PClauses _ _ elabn _)+   | Just (True, _, _) <- clookup n ns+          = do ist <- getIState+               case lookupDefExact elabn (tt_ctxt ist) of+                    Just (CaseOp _ _ _ _ _ cdefs) ->+                       checkInjectiveCase ist (snd (cases_compiletime cdefs))+  where+    checkInjectiveCase ist (STerm tm)+         = checkInjectiveApp ist (fst (unApply tm))+    checkInjectiveCase _ _ = notifail++    checkInjectiveApp ist (P (TCon _ _) n _) = return ()+    checkInjectiveApp ist (P (DCon _ _ _) n _) = return ()+    checkInjectiveApp ist (P Ref n _)+        | Just True <- lookupInjectiveExact n (tt_ctxt ist) = return ()+    checkInjectiveApp ist (P Ref n _) = notifail+    checkInjectiveApp _ _ = notifail++    notifail = ierror $ At fc (Msg (show n ++ " must be defined by a type or data constructor"))++    clookup n [] = Nothing+    clookup n ((n', d) : ds) | nsroot n == nsroot n' = Just d+                             | otherwise = Nothing+checkInjectiveDef fc ns _ = return()++checkInjectiveArgs :: FC -> Name -> [Int] -> Maybe Type -> Idris ()+checkInjectiveArgs fc n ds Nothing = return ()+checkInjectiveArgs fc n ds (Just ty)+   = do ist <- getIState+        let (_, args) = unApply (instantiateRetTy ty)+        ci 0 ist args+  where+    ci i ist (a : as) | i `elem` ds+       = if isInj ist a then ci (i + 1) ist as+            else tclift $ tfail (At fc (InvalidTCArg n a))+    ci i ist (a : as) = ci (i + 1) ist as+    ci i ist [] = return ()++    isInj i (P Bound n _) = True+    isInj i (P _ n _) = isConName n (tt_ctxt i)+    isInj i (App _ f a) = isInj i f && isInj i a+    isInj i (V _) = True+    isInj i (Bind n b sc) = isInj i sc+    isInj _ _ = True++    instantiateRetTy (Bind n (Pi _ _ _) sc)+       = substV (P Bound n Erased) (instantiateRetTy sc)+    instantiateRetTy t = t
− src/Idris/Elab/Instance.hs
@@ -1,504 +0,0 @@-{-|-Module      : Idris.Elab.Instance-Description : Code to elaborate instances.-Copyright   :-License     : BSD3-Maintainer  : The Idris Community.--}-{-# LANGUAGE PatternGuards #-}-module Idris.Elab.Instance(elabInstance) where--import Idris.AbsSyntax-import Idris.ASTUtils-import Idris.DSL-import Idris.Error-import Idris.Delaborate-import Idris.Imports-import Idris.Coverage-import Idris.DataOpts-import Idris.Providers-import Idris.Primitives-import Idris.Inliner-import Idris.PartialEval-import Idris.DeepSeq-import Idris.Output (iputStrLn, pshow, iWarn, sendHighlighting)-import IRTS.Lang--import Idris.Elab.Type-import Idris.Elab.Data-import Idris.Elab.Utils-import Idris.Elab.Term--import Idris.Core.TT-import Idris.Core.Elaborate hiding (Tactic(..))-import Idris.Core.Evaluate-import Idris.Core.Execute-import Idris.Core.Typecheck-import Idris.Core.CaseTree--import Idris.Docstrings--import Prelude hiding (id, (.))-import Control.Category--import Control.Applicative hiding (Const)-import Control.DeepSeq-import Control.Monad-import Control.Monad.State.Strict as State-import Data.List-import Data.Maybe-import Debug.Trace--import qualified Data.Map as Map-import qualified Data.Set as S-import qualified Data.Text as T-import Data.Char(isLetter, toLower)-import Data.List.Split (splitOn)--import Util.Pretty(pretty, text)--elabInstance :: ElabInfo-             -> SyntaxInfo-             -> Docstring (Either Err PTerm)-             -> [(Name, Docstring (Either Err PTerm))]-             -> ElabWhat        -- ^ phase-             -> FC-             -> [(Name, PTerm)] -- ^ constraints-             -> [Name]          -- ^ parent dictionary names (optionally)-             -> Accessibility-             -> FnOpts-             -> Name            -- ^ the class-             -> FC              -- ^ precise location of class name-             -> [PTerm]         -- ^ class parameters (i.e. instance)-             -> [(Name, PTerm)] -- ^ Extra arguments in scope (e.g. instance in where block)-             -> PTerm           -- ^ full instance type-             -> Maybe Name      -- ^ explicit name-             -> [PDecl]-             -> Idris ()-elabInstance info syn doc argDocs what fc cs parents acc opts n nfc ps pextra t expn ds = do-    ist <- getIState-    (n, ci) <- case lookupCtxtName n (idris_classes ist) of-                  [c] -> return c-                  [] -> ifail $ show fc ++ ":" ++ show n ++ " is not an interface"-                  cs -> tclift $ tfail $ At fc-                           (CantResolveAlts (map fst cs))-    let constraint = PApp fc (PRef fc [] n) (map pexp ps)-    let iname = mkiname n (namespace info) ps expn-    putIState (ist { hide_list = addDef iname acc (hide_list ist) })-    ist <- getIState--    let totopts = Dictionary : Inlinable : opts--    let emptyclass = null (class_methods ci)-    when (what /= EDefns) $ do-         nty <- elabType' True info syn doc argDocs fc totopts iname NoFC-                          (piBindp expl_param pextra t)-         -- if the instance type matches any of the instances we have already,-         -- and it's not a named instance, then it's overlapping, so report an error-         case expn of-            Nothing -> do mapM_ (maybe (return ()) overlapping . findOverlapping ist (class_determiners ci) (delab ist nty))-                                (map fst $ class_instances ci)-                          addInstance intInst True n iname-            Just _ -> addInstance intInst False n iname-    when (what /= ETypes && (not (null ds && not emptyclass))) $ do-         -- Add the parent implementation names to the privileged set-         oldOpen <- addOpenImpl parents--         let ips = zip (class_params ci) ps-         let ns = case n of-                    NS n ns' -> ns'-                    _ -> []-         -- get the implicit parameters that need passing through to the-         -- where block-         wparams <- mapM (\p -> case p of-                                  PApp _ _ args -> getWParams (map getTm args)-                                  a@(PRef fc _ f) -> getWParams [a]-                                  _ -> return []) ps-         ist <- getIState-         let pnames = nub $ map pname (concat (nub wparams)) ++-                          concatMap (namesIn [] ist) ps--         let superclassInstances = map (substInstance ips pnames) (class_default_superclasses ci)-         undefinedSuperclassInstances <- filterM (fmap not . isOverlapping ist) superclassInstances-         mapM_ (rec_elabDecl info EAll info) undefinedSuperclassInstances--         ist <- getIState-         -- Bring variables in instance head into scope when building the-         -- dictionary-         let headVars = nub $ concatMap getHeadVars ps-         let (headVarTypes, ty)-                = case lookupTyExact iname (tt_ctxt ist) of-                              Just ty -> (map (\n -> (n, getTypeIn ist n ty)) headVars, ty)-                              _ -> (zip headVars (repeat Placeholder), Erased)-         logElab 3 $ "Head var types " ++ show headVarTypes ++ " from " ++ show ty--         let all_meths = map (nsroot . fst) (class_methods ci)-         let mtys = map (\ (n, (inj, op, t)) ->-                   let t_in = substMatchesShadow ips pnames t-                       mnamemap =-                          map (\n -> (n, PApp fc (PRef fc [] (decorate ns iname n))-                                              (map (toImp fc) headVars)))-                                      all_meths-                       t' = substMatchesShadow mnamemap pnames t_in in-                       (decorate ns iname n,-                           op, coninsert cs pextra t', t'))-              (class_methods ci)-         logElab 3 (show (mtys, ips))-         logElab 5 ("Before defaults: " ++ show ds ++ "\n" ++ show (map fst (class_methods ci)))-         let ds_defs = insertDefaults ist iname (class_defaults ci) ns ds-         logElab 3 ("After defaults: " ++ show ds_defs ++ "\n")-         let ds' = reorderDefs (map fst (class_methods ci)) ds_defs-         logElab 1 ("Reordered: " ++ show ds' ++ "\n")--         mapM_ (warnMissing ds' ns iname) (map fst (class_methods ci))-         mapM_ (checkInClass (map fst (class_methods ci))) (concatMap defined ds')-         let wbTys = map mkTyDecl mtys-         let wbVals_orig = map (decorateid (decorate ns iname)) ds'-         ist <- getIState-         let wbVals = map (expandParamsD False ist id pextra (map methName mtys)) wbVals_orig-         let wb = wbTys ++ wbVals--         logElab 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)-         logElab 3 $ "Instance is " ++ show ps ++ " implicits " ++-                                      show (concat (nub wparams))---         let lhsImps = map (\n -> pimp n (PRef fc [] n) True) headVars--         let lhs = PApp fc (PRef fc [] iname) (lhsImps ++ map (toExp .fst) pextra)-         let rhs = PApp fc (PRef fc [] (instanceCtorName ci))-                           (map (pexp . (mkMethApp lhsImps)) mtys)--         logElab 5 $ "Instance LHS " ++ show totopts ++ "\n" ++ showTmImpls lhs ++ " " ++ show headVars-         logElab 5 $ "Instance RHS " ++ show rhs--         push_estack iname True-         logElab 3 ("Method types: " ++ show wbTys)-         logElab 3 ("Method bodies (before params): " ++ show wbVals_orig)-         logElab 3 ("Method bodies: " ++ show wbVals)--         let idecls = [PClauses fc totopts iname-                              [PClause fc iname lhs [] rhs []]]--         mapM_ (rec_elabDecl info EAll info) (map (impBind headVarTypes) wbTys)-         mapM_ (rec_elabDecl info EAll info) idecls--         ctxt <- getContext-         let ifn_ty = case lookupTyExact iname ctxt of-                           Just t -> t-                           Nothing -> error "Can't happen (interface constructor)"-         let ifn_is = case lookupCtxtExact iname (idris_implicits ist) of-                           Just t -> t-                           Nothing -> []-         let prop_params = getParamsInType ist [] ifn_is ifn_ty--         logElab 3 $ "Propagating parameters to methods: "-                           ++ show (iname, prop_params)--         let wbVals' = map (addParams prop_params) wbVals--         mapM_ (rec_elabDecl info EAll info) wbVals'--         mapM_ (checkInjectiveDef fc (class_methods ci)) (zip ds' wbVals')--         pop_estack--         setOpenImpl oldOpen---          totalityCheckBlock--         checkInjectiveArgs fc n (class_determiners ci) (lookupTyExact iname (tt_ctxt ist))-         addIBC (IBCInstance intInst (isNothing expn) n iname)--  where-    intInst = case ps of-                [PConstant NoFC (AType (ATInt ITNative))] -> True-                _ -> False--    mkiname n' ns ps' expn' =-        case expn' of-          Nothing -> case ns of-                          [] -> SN (sInstanceN n' (map show ps'))-                          m -> sNS (SN (sInstanceN n' (map show ps'))) m-          Just nm -> nm--    substInstance ips pnames (PInstance doc argDocs syn _ cs parents acc opts n nfc ps pextra t expn ds)-        = PInstance doc argDocs syn fc cs parents acc opts n nfc-                     (map (substMatchesShadow ips pnames) ps)-                     pextra-                     (substMatchesShadow ips pnames t) expn ds--    isOverlapping i (PInstance doc argDocs syn _ _ _ _ _ n nfc ps pextra t expn _)-        = case lookupCtxtName n (idris_classes i) of-            [(n, ci)] -> let iname = (mkiname n (namespace info) ps expn) in-                            case lookupTy iname (tt_ctxt i) of-                              [] -> elabFindOverlapping i ci iname syn t-                              (_:_) -> return True-            _ -> return False -- couldn't find class, just let elabInstance fail later--    -- TODO: largely based upon elabType' - should try to abstract-    -- Issue #1614 in the issue tracker:-    --    https://github.com/idris-lang/Idris-dev/issues/1614-    elabFindOverlapping i ci iname syn t-        = do ty' <- addUsingConstraints syn fc t-             -- TODO think: something more in info?-             ty' <- implicit info syn iname ty'-             let ty = addImpl [] i ty'-             ctxt <- getContext-             (ElabResult tyT _ _ ctxt' newDecls highlights newGName, _) <--                tclift $ elaborate (constraintNS info) ctxt (idris_datatypes i) (idris_name i) iname (TType (UVal 0)) initEState-                         (errAt "type of " iname Nothing (erun fc (build i info ERHS [] iname ty)))-             setContext ctxt'-             processTacticDecls info newDecls-             sendHighlighting highlights-             updateIState $ \i -> i { idris_name = newGName }--             ctxt <- getContext-             (cty, _) <- recheckC (constraintNS info) fc id [] tyT-             let nty = normalise ctxt [] cty-             return $ any (isJust . findOverlapping i (class_determiners ci) (delab i nty)) (map fst $ class_instances ci)--    findOverlapping i dets t n-     | SN (ParentN _ _) <- n = Nothing-     | otherwise-        = case lookupTy n (tt_ctxt i) of-            [t'] -> let tret = getRetType t-                        tret' = getRetType (delab i t') in-                        case matchArgs i dets tret' tret of-                           Right _ -> Just tret'-                           Left _ -> case matchArgs i dets tret tret' of-                                       Right _ -> Just tret'-                                       Left _ -> Nothing-            _ -> Nothing-    overlapping t' = tclift $ tfail (At fc (Msg $-                          "Overlapping implementation: " ++ show t' ++ " already defined"))-    getRetType (PPi _ _ _ _ sc) = getRetType sc-    getRetType t = t--    matchArgs i dets x y =-        let x' = keepDets dets x-            y' = keepDets dets y in-            matchClause i x' y'--    keepDets dets (PApp fc f args)-        = PApp fc f $ let a' = zip [0..] args in-              map snd (filter (\(i, _) -> i `elem` dets) a')-    keepDets dets t = t--    methName (n, _, _, _) = n-    toExp n = pexp (PRef fc [] n)--    mkMethApp ps (n, _, _, ty)-              = lamBind 0 ty (papp fc (PRef fc [] n)-                     (ps ++ map (toExp . fst) pextra ++ methArgs 0 ty))-       where-          needed is p = pname p `elem` map pname is--    lamBind i (PPi (Constraint _ _) _ _ _ sc) sc'-          = PLam fc (sMN i "meth") NoFC Placeholder (lamBind (i+1) sc sc')-    lamBind i (PPi _ n _ ty sc) sc'-          = PLam fc (sMN i "meth") NoFC Placeholder (lamBind (i+1) sc sc')-    lamBind i _ sc = sc-    methArgs i (PPi (Imp _ _ _ _ _) n _ ty sc)-        = PImp 0 True [] n (PRef fc [] (sMN i "meth")) : methArgs (i+1) sc-    methArgs i (PPi (Exp _ _ _) n _ ty sc)-        = PExp 0 [] (sMN 0 "marg") (PRef fc [] (sMN i "meth")) : methArgs (i+1) sc-    methArgs i (PPi (Constraint _ _) n _ ty sc)-        = PConstraint 0 [] (sMN 0 "marg") (PResolveTC fc) : methArgs (i+1) sc-    methArgs i _ = []--    papp fc f [] = f-    papp fc f as = PApp fc f as--    getWParams [] = return []-    getWParams (p : ps)-      | PRef _ _ n <- p-        = do ps' <- getWParams ps-             ctxt <- getContext-             case lookupP n ctxt of-                [] -> return (pimp n (PRef fc [] n) True : ps')-                _ -> return ps'-    getWParams (_ : ps) = getWParams ps--    decorate ns iname (NS (UN nm) s)-         = NS (SN (WhereN 0 iname (SN (MethodN (UN nm))))) ns-    decorate ns iname nm-         = NS (SN (WhereN 0 iname (SN (MethodN nm)))) ns--    mkTyDecl (n, op, t, _)-        = PTy emptyDocstring [] syn fc op n NoFC-               (mkUniqueNames [] [] t)--    conbind :: [(Name, PTerm)] -> PTerm -> PTerm-    conbind ((c,ty) : ns) x = PPi constraint c NoFC ty (conbind ns x)-    conbind [] x = x--    extrabind :: [(Name, PTerm)] -> PTerm -> PTerm-    extrabind ((c,ty) : ns) x = PPi expl c NoFC ty (extrabind ns x)-    extrabind [] x = x--    coninsert :: [(Name, PTerm)] -> [(Name, PTerm)] -> PTerm -> PTerm-    coninsert cs ex (PPi p@(Imp _ _ _ _ _) n fc t sc) = PPi p n fc t (coninsert cs ex sc)-    coninsert cs ex sc = conbind cs (extrabind ex sc)--    -- Reorder declarations to be in the same order as defined in the-    -- class declaration (important so that we insert default definitions-    -- in the right place, and so that dependencies between methods are-    -- respected)-    reorderDefs :: [Name] -> [PDecl] -> [PDecl]-    reorderDefs ns [] = []-    reorderDefs [] ds = ds-    reorderDefs (n : ns) ds = case pick n [] ds of-                                  Just (def, ds') -> def : reorderDefs ns ds'-                                  Nothing -> reorderDefs ns ds--    pick n acc [] = Nothing-    pick n acc (def@(PClauses _ _ cn cs) : ds)-         | nsroot n == nsroot cn = Just (def, acc ++ ds)-    pick n acc (d : ds) = pick n (acc ++ [d]) ds--    insertDefaults :: IState -> Name ->-                      [(Name, (Name, PDecl))] -> [T.Text] ->-                      [PDecl] -> [PDecl]-    insertDefaults i iname [] ns ds = ds-    insertDefaults i iname ((n,(dn, clauses)) : defs) ns ds-       = insertDefaults i iname defs ns (insertDef i n dn clauses ns iname ds)--    insertDef i meth def clauses ns iname decls-        | not $ any (clauseFor meth iname ns) decls-            = let newd = expandParamsD False i (\n -> meth) [] [def] clauses in-                  -- trace (show newd) $-                  decls ++ [newd]-        | otherwise = decls--    warnMissing decls ns iname meth-        | not $ any (clauseFor meth iname ns) decls-            = iWarn fc . text $ "method " ++ show meth ++ " not defined"-        | otherwise = return ()--    checkInClass ns meth-        | any (eqRoot meth) ns = return ()-        | otherwise = tclift $ tfail (At fc (Msg $-                                show meth ++ " not a method of class " ++ show n))--    eqRoot x y = nsroot x == nsroot y--    clauseFor m iname ns (PClauses _ _ m' _)-       = decorate ns iname m == decorate ns iname m'-    clauseFor m iname ns _ = False--getHeadVars :: PTerm -> [Name]-getHeadVars (PRef _ _ n) | implicitable n = [n]-getHeadVars (PApp _ _ args) = concatMap getHeadVars (map getTm args)-getHeadVars (PPair _ _ _ l r) = getHeadVars l ++ getHeadVars r-getHeadVars (PDPair _ _ _ l t r) = getHeadVars l ++ getHeadVars t ++ getHeadVars t-getHeadVars _ = []---- | Implicitly bind variables from the instance head in method types-impBind :: [(Name, PTerm)] -> PDecl -> PDecl-impBind vs (PTy d ds syn fc opts n fc' t)-     = PTy d ds syn fc opts n fc'-          (doImpBind (filter (\(n, ty) -> n `notElem` boundIn t) vs) t)-  where-    doImpBind [] ty = ty-    doImpBind ((n, argty) : ns) ty-       = PPi impl n NoFC argty (doImpBind ns ty)--    boundIn (PPi _ n _ _ sc) = n : boundIn sc-    boundIn _ = []--getTypeIn :: IState -> Name -> Type -> PTerm-getTypeIn ist n (Bind x b sc)-    | n == x = delab ist (binderTy b)-    | otherwise = getTypeIn ist n (substV (P Ref x Erased) sc)-getTypeIn ist n tm = Placeholder--toImp fc n = pimp n (PRef fc [] n) True---- | Propagate class parameters to method bodies, if they're not--- already there, and they are needed (i.e. appear in method's type)-addParams :: [Name] -> PDecl -> PDecl-addParams ps (PClauses fc opts n cs) = PClauses fc opts n (map addCParams cs)-  where-    addCParams (PClause fc n lhs ws rhs wb)-        = PClause fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws rhs wb-    addCParams (PWith fc n lhs ws sc pn ds)-        = PWith fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws sc pn-                      (map (addParams ps) ds)-    addCParams c = c--    addTmParams ps (PRef fc hls n)-        = PApp fc (PRef fc hls n) (map (toImp fc) ps)-    addTmParams ps (PApp fc ap@(PRef fc' hls n) args)-        = PApp fc ap (mergePs (map (toImp fc) ps) args)-    addTmParams ps tm = tm--    mergePs [] args = args-    mergePs (p : ps) args-         | isImplicit p,-           pname p `notElem` map pname args-               = p : mergePs ps args-       where-         isImplicit (PExp{}) = False-         isImplicit _ = True-    mergePs (p : ps) args-         = mergePs ps args--    -- Don't propagate a parameter if the name is rebound explicitly-    dropPs :: [Name] -> [Name] -> [Name]-    dropPs ns = filter (\x -> x `notElem` ns)--addParams ps d = d---- | Check a given method definition is injective, if the class info--- says it needs to be.  Takes originally written decl and the one--- with name decoration, so we know which name to look up.-checkInjectiveDef :: FC -> [(Name, (Bool, FnOpts, PTerm))] ->-                           (PDecl, PDecl) -> Idris ()-checkInjectiveDef fc ns (PClauses _ _ n cs, PClauses _ _ elabn _)-   | Just (True, _, _) <- clookup n ns-          = do ist <- getIState-               case lookupDefExact elabn (tt_ctxt ist) of-                    Just (CaseOp _ _ _ _ _ cdefs) ->-                       checkInjectiveCase ist (snd (cases_compiletime cdefs))-  where-    checkInjectiveCase ist (STerm tm)-         = checkInjectiveApp ist (fst (unApply tm))-    checkInjectiveCase _ _ = notifail--    checkInjectiveApp ist (P (TCon _ _) n _) = return ()-    checkInjectiveApp ist (P (DCon _ _ _) n _) = return ()-    checkInjectiveApp ist (P Ref n _)-        | Just True <- lookupInjectiveExact n (tt_ctxt ist) = return ()-    checkInjectiveApp ist (P Ref n _) = notifail-    checkInjectiveApp _ _ = notifail--    notifail = ierror $ At fc (Msg (show n ++ " must be defined by a type or data constructor"))--    clookup n [] = Nothing-    clookup n ((n', d) : ds) | nsroot n == nsroot n' = Just d-                             | otherwise = Nothing-checkInjectiveDef fc ns _ = return()--checkInjectiveArgs :: FC -> Name -> [Int] -> Maybe Type -> Idris ()-checkInjectiveArgs fc n ds Nothing = return ()-checkInjectiveArgs fc n ds (Just ty)-   = do ist <- getIState-        let (_, args) = unApply (instantiateRetTy ty)-        ci 0 ist args-  where-    ci i ist (a : as) | i `elem` ds-       = if isInj ist a then ci (i + 1) ist as-            else tclift $ tfail (At fc (InvalidTCArg n a))-    ci i ist (a : as) = ci (i + 1) ist as-    ci i ist [] = return ()--    isInj i (P Bound n _) = True-    isInj i (P _ n _) = isConName n (tt_ctxt i)-    isInj i (App _ f a) = isInj i f && isInj i a-    isInj i (V _) = True-    isInj i (Bind n b sc) = isInj i sc-    isInj _ _ = True--    instantiateRetTy (Bind n (Pi _ _ _) sc)-       = substV (P Bound n Erased) (instantiateRetTy sc)-    instantiateRetTy t = t
+ src/Idris/Elab/Interface.hs view
@@ -0,0 +1,368 @@+{-|+Module      : Idris.Elab.Interface+Description : Code to elaborate interfaces.+Copyright   :+License     : BSD3+Maintainer  : The Idris Community.+-}+{-# LANGUAGE PatternGuards #-}+{-# OPTIONS_GHC -fwarn-missing-signatures #-}+module Idris.Elab.Interface(elabInterface) where++import Idris.AbsSyntax+import Idris.ASTUtils+import Idris.DSL+import Idris.Error+import Idris.Delaborate+import Idris.Imports+import Idris.Elab.Term+import Idris.Coverage+import Idris.DataOpts+import Idris.Providers+import Idris.Primitives+import Idris.Inliner+import Idris.PartialEval+import Idris.DeepSeq+import Idris.Output (iputStrLn, pshow, iWarn, sendHighlighting)+import IRTS.Lang++import Idris.Elab.Type+import Idris.Elab.Data+import Idris.Elab.Utils++import Idris.Core.TT+import Idris.Core.Elaborate hiding (Tactic(..))+import Idris.Core.Evaluate+import Idris.Core.Execute+import Idris.Core.Typecheck+import Idris.Core.CaseTree++import Idris.Docstrings++import Prelude hiding (id, (.))+import Control.Category++import Control.Applicative hiding (Const)+import Control.DeepSeq+import Control.Monad+import Control.Monad.State.Strict as State+import Data.List+import Data.Maybe+import Debug.Trace++import qualified Data.Map as Map+import qualified Data.Set as S+import qualified Data.Text as T+import Data.Char(isLetter, toLower)+import Data.List.Split (splitOn)+import Data.Generics.Uniplate.Data (transform)++import Util.Pretty(pretty, text)++data MArgTy = IA Name | EA Name | CA deriving Show++elabInterface :: ElabInfo+              -> SyntaxInfo+              -> Docstring (Either Err PTerm)+              -> FC+              -> [(Name, PTerm)]+              -> Name+              -> FC+              -> [(Name, FC, PTerm)]+              -> [(Name, Docstring (Either Err PTerm))]+              -> [(Name, FC)]                 -- ^ determining params+              -> [PDecl]                      -- ^ interface body+              -> Maybe (Name, FC)             -- ^ implementation ctor name and location+              -> Docstring (Either Err PTerm) -- ^ implementation ctor docs+              -> Idris ()+elabInterface info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd+    = do let cn = fromMaybe (SN (ImplementationCtorN tn)) (fst <$> mcn)+         let tty = pibind (map (\(n, _, ty) -> (n, ty)) ps) (PType fc)+         let constraint = PApp fc (PRef fc [] tn)+                                  (map (pexp . PRef fc []) (map (\(n, _, _) -> n) ps))++         let syn =+              syn_in { using = addToUsing (using syn_in)+                                 [(pn, pt) | (pn, _, pt) <- ps]+                     }++         -- build data declaration+         let mdecls = filter tydecl ds -- method declarations+         let idecls = filter impldecl ds -- default super interface implementation declarations+         mapM_ checkDefaultSuperInterfaceImplementation idecls+         let mnames = map getMName mdecls+         ist <- getIState+         let constraintNames = nub $+                 concatMap (namesIn [] ist) (map snd constraints)++         mapM_ (checkConstraintName (map (\(x, _, _) -> x) ps)) constraintNames++         logElab 2 $ "Building methods " ++ show mnames+         ims <- mapM (tdecl mnames) mdecls+         defs <- mapM (defdecl (map (\ (x,y,z) -> z) ims) constraint)+                      (filter clause ds)+         let (methods, imethods)+              = unzip (map (\ (x, y, z) -> (x, y)) ims)+         let defaults = map (\ (x, (y, z)) -> (x,y)) defs++         -- build implementation constructor type+         let cty = impbind [(pn, pt) | (pn, _, pt) <- ps] $ conbind constraints+                      $ pibind (map (\ (n, ty) -> (nsroot n, ty)) methods)+                               constraint++         let cons = [(cd, pDocs ++ mapMaybe memberDocs ds, cn, NoFC, cty, fc, [])]+         let ddecl = PDatadecl tn NoFC tty cons++         logElab 5 $ "Interface data " ++ show (showDImp verbosePPOption ddecl)++         -- Elaborate the data declaration+         elabData info (syn { no_imp = no_imp syn ++ mnames,+                              imp_methods = mnames }) doc pDocs fc [] ddecl+         dets <- findDets cn (map fst fds)+         addInterface tn (CI cn (map nodoc imethods) defaults idecls (map (\(n, _, _) -> n) ps) [] dets)++         -- for each constraint, build a top level function to chase it+         cfns <- mapM (cfun cn constraint syn (map fst imethods)) constraints+         mapM_ (rec_elabDecl info EAll info) (concat cfns)++         -- for each method, build a top level function+         fns <- mapM (tfun cn constraint (syn { imp_methods = mnames })+                           (map fst imethods)) imethods+         logElab 5 $ "Functions " ++ show fns+         -- Elaborate the the top level methods+         mapM_ (rec_elabDecl info EAll info) (concat fns)++         -- Flag all the top level data declarations as injective+         mapM_ (\n -> do setInjectivity n True+                         addIBC (IBCInjective n True))+               (map fst (filter (\(_, (inj, _, _, _, _)) -> inj) imethods))++         -- add the default definitions+         mapM_ (rec_elabDecl info EAll info) (concatMap (snd.snd) defs)+         addIBC (IBCInterface tn)++         sendHighlighting $+           [(tnfc, AnnName tn Nothing Nothing Nothing)] +++           [(pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] +++           [(fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] +++           maybe [] (\(conN, conNFC) -> [(conNFC, AnnName conN Nothing Nothing Nothing)]) mcn++  where+    nodoc (n, (inj, _, _, o, t)) = (n, (inj, o, t))++    pibind [] x = x+    pibind ((n, ty): ns) x = PPi expl n NoFC ty (pibind ns (chkUniq ty x))++    -- To make sure the type constructor of the interface is in the appropriate+    -- uniqueness hierarchy+    chkUniq u@(PUniverse _ _) (PType _) = u+    chkUniq (PUniverse _ l) (PUniverse _ r) = PUniverse NoFC (min l r)+    chkUniq (PPi _ _ _ _ sc) t = chkUniq sc t+    chkUniq _ t = t++    -- TODO: probably should normalise+    checkDefaultSuperInterfaceImplementation :: PDecl -> Idris ()+    checkDefaultSuperInterfaceImplementation (PImplementation _ _ _ fc cs _ _ _ n _ ps _ _ _ _)+        = do when (not $ null cs) . tclift+                $ tfail (At fc (Msg "Default super interface implementations can't have constraints."))+             i <- getIState+             let t = PApp fc (PRef fc [] n) (map pexp ps)+             let isConstrained = any (== t) (map snd constraints)+             when (not isConstrained) . tclift+                $ tfail (At fc (Msg "Default implementations must be for a super interface constraint on the containing interface."))+             return ()++    checkConstraintName :: [Name] -> Name -> Idris ()+    checkConstraintName bound cname+        | cname `notElem` bound+            = tclift $ tfail (At fc (Msg $ "Name " ++ show cname +++                         " is not bound in interface " ++ show tn+                         ++ " " ++ showSep " " (map show bound)))+        | otherwise = return ()++    impbind :: [(Name, PTerm)] -> PTerm -> PTerm+    impbind [] x = x+    impbind ((n, ty): ns) x = PPi impl n NoFC ty (impbind ns x)++    conbind :: [(Name, PTerm)] -> PTerm -> PTerm+    conbind ((c, ty) : ns) x = PPi constraint c NoFC ty (conbind ns x)+    conbind [] x = x++    getMName (PTy _ _ _ _ _ n nfc _) = nsroot n+    getMName (PData _ _ _ _ _ (PLaterdecl n nfc _)) = nsroot n++    tdecl allmeths (PTy doc _ syn _ o n nfc t)+           = do t' <- implicit' info syn (map (\(n, _, _) -> n) ps ++ allmeths) n t+                logElab 2 $ "Method " ++ show n ++ " : " ++ showTmImpls t'+                return ( (n, (toExp (map (\(pn, _, _) -> pn) ps) Exp t')),+                         (n, (False, nfc, doc, o, (toExp (map (\(pn, _, _) -> pn) ps)+                                              (\ l s p -> Imp l s p Nothing True) t'))),+                         (n, (nfc, syn, o, t) ) )+    tdecl allmeths (PData doc _ syn _ _ (PLaterdecl n nfc t))+           = do let o = []+                t' <- implicit' info syn (map (\(n, _, _) -> n) ps ++ allmeths) n t+                logElab 2 $ "Data method " ++ show n ++ " : " ++ showTmImpls t'+                return ( (n, (toExp (map (\(pn, _, _) -> pn) ps) Exp t')),+                         (n, (True, nfc, doc, o, (toExp (map (\(pn, _, _) -> pn) ps)+                                              (\ l s p -> Imp l s p Nothing True) t'))),+                         (n, (nfc, syn, o, t) ) )+    tdecl allmeths (PData doc _ syn _ _ _)+         = ierror $ At fc (Msg "Data definitions not allowed in an interface declaration")+    tdecl _ _ = ierror $ At fc (Msg "Not allowed in an interface declaration")++    -- Create default definitions+    defdecl mtys c d@(PClauses fc opts n cs) =+        case lookup n mtys of+            Just (nfc, syn, o, ty) ->+              do let ty' = insertConstraint c (map fst mtys) ty+                 let ds = map (decorateid defaultdec)+                              [PTy emptyDocstring [] syn fc [] n nfc ty',+                               PClauses fc (o ++ opts) n cs]+                 logElab 1 (show ds)+                 return (n, ((defaultdec n, ds!!1), ds))+            _ -> ierror $ At fc (Msg (show n ++ " is not a method"))+    defdecl _ _ _ = ifail "Can't happen (defdecl)"++    defaultdec (UN n) = sUN ("default#" ++ str n)+    defaultdec (NS n ns) = NS (defaultdec n) ns++    tydecl (PTy{}) = True+    tydecl (PData _ _ _ _ _ _) = True+    tydecl _ = False+    impldecl (PImplementation{}) = True+    impldecl _ = False+    clause (PClauses{}) = True+    clause _ = False++    -- Generate a function for chasing a dictionary constraint+    cfun :: Name -> PTerm -> SyntaxInfo -> [a] -> (Name, PTerm) -> Idris [PDecl' PTerm]+    cfun cn c syn all (cnm, con)+        = do let cfn = SN (ParentN cn (txt (show con)))+             let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]+             let capp = PApp fc (PRef fc [] cn) (map (pexp . PRef fc []) mnames)+             let lhs = PApp fc (PRef fc [] cfn) [pconst capp]+             let rhs = PResolveTC (fileFC "HACK")+             let ty = PPi constraint cnm NoFC c con+             logElab 2 ("Dictionary constraint: " ++ showTmImpls ty)+             logElab 2 (showTmImpls lhs ++ " = " ++ showTmImpls rhs)+             i <- getIState+             let conn = case con of+                            PRef _ _ n -> n+                            PApp _ (PRef _ _ n) _ -> n+             let conn' = case lookupCtxtName conn (idris_interfaces i) of+                                [(n, _)] -> n+                                _ -> conn+             addImplementation False True conn' cfn+             addIBC (IBCImplementation False True conn' cfn)+--              iputStrLn ("Added " ++ show (conn, cfn, ty))+             return [PTy emptyDocstring [] syn fc [] cfn NoFC ty,+                     PClauses fc [Inlinable, Dictionary] cfn [PClause fc cfn lhs [] rhs []]]++    -- | Generate a top level function which looks up a method in a given+    -- dictionary (this is inlinable, always)+    tfun :: Name -- ^ The name of the interface+         -> PTerm -- ^ A constraint for the interface, to be inserted under the implicit bindings+         -> SyntaxInfo -> [Name] -- ^ All the method names+         -> (Name, (Bool, FC, Docstring (Either Err PTerm), FnOpts, PTerm))+            -- ^ The present declaration+         -> Idris [PDecl]+    tfun cn c syn all (m, (isdata, mfc, doc, o, ty))+        = do let ty' = expandMethNS syn (insertConstraint c all ty)+             let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]+             let capp = PApp fc (PRef fc [] cn) (map (pexp . PRef fc []) mnames)+             let margs = getMArgs ty+             let anames = map (\x -> sMN x "arg") [0..]+             let lhs = PApp fc (PRef fc [] m) (pconst capp : lhsArgs margs anames)+             let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)+             logElab 2 ("Top level type: " ++ showTmImpls ty')+             logElab 1 (show (m, ty', capp, margs))+             logElab 2 ("Definition: " ++ showTmImpls lhs ++ " = " ++ showTmImpls rhs)+             return [PTy doc [] syn fc o m mfc ty',+                     PClauses fc [Inlinable] m [PClause fc m lhs [] rhs []]]++    getMArgs (PPi (Imp _ _ _ _ _) n _ ty sc) = IA n : getMArgs sc+    getMArgs (PPi (Exp _ _ _) n _ ty sc) = EA n : getMArgs sc+    getMArgs (PPi (Constraint _ _) n _ ty sc) = CA : getMArgs sc+    getMArgs _ = []++    getMeth :: [Name] -> [Name] -> Name -> PTerm+    getMeth (m:ms) (a:as) x | x == a = PRef fc [] m+                            | otherwise = getMeth ms as x++    lhsArgs (EA _ : xs) (n : ns) = [] -- pexp (PRef fc n) : lhsArgs xs ns+    lhsArgs (IA n : xs) ns = pimp n (PRef fc [] n) False : lhsArgs xs ns+    lhsArgs (CA : xs) ns = lhsArgs xs ns+    lhsArgs [] _ = []++    rhsArgs (EA _ : xs) (n : ns) = [] -- pexp (PRef fc n) : rhsArgs xs ns+    rhsArgs (IA n : xs) ns = pexp (PRef fc [] n) : rhsArgs xs ns+    rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns+    rhsArgs [] _ = []++    -- Add the top level constraint. Put it first - elaboration will resolve+    -- the order of the implicits if there are dependencies.+    -- Also ensure the dictionary is used for lookup of any methods that+    -- are used in the type+    insertConstraint :: PTerm -> [Name] -> PTerm -> PTerm+    insertConstraint c all sc+          = let dictN = sMN 0 "__interface" in+                PPi (constraint { pstatic = Static })+                    dictN NoFC c+                    (constrainMeths (map basename all)+                                    dictN sc)+     where+       -- After we insert the constraint into the lookup, we need to+       -- ensure that the same dictionary is used to resolve lookups+       -- to the other methods in the interface+       constrainMeths :: [Name] -> Name -> PTerm -> PTerm+       constrainMeths allM dictN tm = transform (addC allM dictN) tm++       addC allM dictN m@(PRef fc hls n)+          | n `elem` allM = PApp NoFC m [pconst (PRef NoFC hls dictN)]+          | otherwise = m+       addC _ _ tm = tm++    -- make arguments explicit and don't bind interface parameters+    toExp ns e (PPi (Imp l s p _ _) n fc ty sc)+        | n `elem` ns = toExp ns e sc+        | otherwise = PPi (e l s p) n fc ty (toExp ns e sc)+    toExp ns e (PPi p n fc ty sc) = PPi p n fc ty (toExp ns e sc)+    toExp ns e sc = sc++-- | Get the method declaration name corresponding to a user-provided name+mdec :: Name -> Name+mdec (UN n) = SN (MethodN (UN n))+mdec (NS x n) = NS (mdec x) n+mdec x = x++-- | Get the docstring corresponding to a member, if one exists+memberDocs :: PDecl -> Maybe (Name, Docstring (Either Err PTerm))+memberDocs (PTy d _ _ _ _ n _ _) = Just (basename n, d)+memberDocs (PPostulate _ d _ _ _ _ n _) = Just (basename n, d)+memberDocs (PData d _ _ _ _ pdata) = Just (basename $ d_name pdata, d)+memberDocs (PRecord d _ _ _ n _ _ _ _ _ _ _ ) = Just (basename n, d)+memberDocs (PInterface d _ _ _ n _ _ _ _ _ _ _) = Just (basename n, d)+memberDocs _ = Nothing+++-- | In a top level type for a method, expand all the method names' namespaces+-- so that we don't have to disambiguate later+expandMethNS :: SyntaxInfo+                -> PTerm -> PTerm+expandMethNS syn = mapPT expand+  where+    expand (PRef fc hls n) | n `elem` imp_methods syn = PRef fc hls $ expandNS syn n+    expand t = t++-- | Find the determining parameter locations+findDets :: Name -> [Name] -> Idris [Int]+findDets n ns =+    do i <- getIState+       return $ case lookupTyExact n (tt_ctxt i) of+            Just ty -> getDetPos 0 ns ty+            Nothing -> []+  where+    getDetPos i ns (Bind n (Pi _ _ _) sc)+       | n `elem` ns = i : getDetPos (i + 1) ns sc+       | otherwise = getDetPos (i + 1) ns sc+    getDetPos _ _ _ = []
src/Idris/Elab/Rewrite.hs view
@@ -233,7 +233,7 @@   where     fc = emptyFC -    namesFrom x i = sMN i x : namesFrom x (i + 1)+    namesFrom x i = sMN i (x ++ show i) : namesFrom x (i + 1)      mkTy fn pinfo ps is          = PApp fc (PRef fc [] fn) (mkArgs pinfo ps is)
src/Idris/Elab/Term.hs view
@@ -90,17 +90,17 @@                         _ -> False           hs <- get_holes-         ivs <- get_instances+         ivs <- get_implementations          ptm <- get_term-         -- Resolve remaining type classes. Two passes - first to get the-         -- default Num instances, second to clean up the rest+         -- Resolve remaining interfaces. Two passes - first to get the+         -- default Num implementations, second to clean up the rest          when (not pattern) $               mapM_ (\n -> when (n `elem` hs) $                              do focus n                                 g <- goal                                 try (resolveTC' True True 10 g fn ist)                                     (movelast n)) ivs-         ivs <- get_instances+         ivs <- get_implementations          hs <- get_holes          when (not pattern) $               mapM_ (\n -> when (n `elem` hs) $@@ -152,7 +152,7 @@                       (h: hs) -> do patvar h; mkPat                       [] -> return () --- | Build a term autogenerated as a typeclass method definition.+-- | Build a term autogenerated as an interface method definition. -- -- (Separate, so we don't go overboard resolving things that we don't -- know about yet on the LHS of a pattern def)@@ -369,7 +369,10 @@       do apply RType []          solve          highlightSource fc' (AnnType "Type" "The type of types")-    elab' ina fc (PUniverse u)   = do apply (RUType u) []; solve+    elab' ina fc (PUniverse fc' u)   =+      do apply (RUType u) []+         solve+         highlightSource fc' (AnnType (show u) "The type of unique types") --  elab' (_,_,inty) (PConstant c) --     | constType c && pattern && not reflection && not inty --       = lift $ tfail (Msg "Typecase is not allowed")@@ -390,11 +393,11 @@             TType _ -> elab' ina (Just fc) (PRef fc [] unitTy)             UType _ -> elab' ina (Just fc) (PRef fc [] unitTy)             _ -> elab' ina (Just fc) (PRef fc [] unitCon)-    elab' ina fc (PResolveTC (FC "HACK" _ _)) -- for chasing parent classes+    elab' ina fc (PResolveTC (FC "HACK" _ _)) -- for chasing parent interfaces        = do g <- goal; resolveTC False False 5 g fn elabRec ist     elab' ina fc (PResolveTC fc')-        = do c <- getNameFrom (sMN 0 "__class")-             instanceArg c+        = do c <- getNameFrom (sMN 0 "__interface")+             implementationArg c     -- Elaborate the equality type first homogeneously, then     -- heterogeneously as a fallback     elab' ina _ (PApp fc (PRef _ _ n) args)@@ -617,7 +620,7 @@              let defined = case lookupTy n ctxt of                                [] -> False                                _ -> True-           -- this is to stop us resolve type classes recursively+           -- this is to stop us resolve interfaces recursively              -- trace (show (n, guarded)) $              if (tcname n && ina && not intransform)                then erun fc $@@ -718,7 +721,7 @@                highlightSource nfc (AnnBoundName n False)     elab' ina _ tm@(PLet fc n nfc ty val sc)           = do attack-               ivs <- get_instances+               ivs <- get_implementations                tyn <- getNameFrom (sMN 0 "letty")                claim tyn RType                valn <- getNameFrom (sMN 0 "letval")@@ -735,7 +738,7 @@                focus valn                elabE (ina { e_inarg = True, e_intype = True })                      (Just fc) val-               ivs' <- get_instances+               ivs' <- get_implementations                env <- get_env                elabE (ina { e_inarg = True }) (Just fc) sc                when (not (pattern || intransform)) $@@ -858,14 +861,14 @@                          (ffc, annot) : map (\f -> (f, annot)) hls                        return []                else-                 do ivs <- get_instances+                 do ivs <- get_implementations                     ps <- get_probs-                    -- HACK: we shouldn't resolve type classes if we're defining an instance+                    -- HACK: we shouldn't resolve interfaces if we're defining an implementation                     -- function or default definition.                     let isinf = f == inferCon || tcname f-                    -- if f is a type class, we need to know its arguments so that+                    -- if f is an interface, we need to know its arguments so that                     -- we can unify with them-                    case lookupCtxt f (idris_classes ist) of+                    case lookupCtxt f (idris_interfaces ist) of                         [] -> return ()                         _ -> do mapM_ setInjective (map getTm args)                                 -- maybe more things are solvable now@@ -874,7 +877,7 @@ --                    trace ("args is " ++ show args) $ return ()                     ns <- apply (Var f) (map isph args) --                    trace ("ns is " ++ show ns) $ return ()-                    -- mark any type class arguments as injective+                    -- mark any interface arguments as injective --                     when (not pattern) $                      mapM_ checkIfInjective (map snd ns)                     unifyProblems -- try again with the new information,@@ -910,8 +913,8 @@                          rs@(_:_) | not pattern -> return rs -- quit, try again                          _ -> do solve                                  hs <- get_holes-                                 ivs' <- get_instances-                                 -- Attempt to resolve any type classes which have 'complete' types,+                                 ivs' <- get_implementations+                                 -- Attempt to resolve any interfaces which have 'complete' types,                                  -- i.e. no holes in them                                  when (not pattern || (e_inarg ina && not tcgen)) $                                      mapM_ (\n -> do focus n@@ -958,10 +961,10 @@                      Just b ->                        case unApply (normalise (tt_ctxt ist) env (binderTy b)) of                             (P _ c _, args) ->-                                case lookupCtxtExact c (idris_classes ist) of+                                case lookupCtxtExact c (idris_interfaces ist) of                                    Nothing -> return ()-                                   Just ci -> -- type class, set as injective-                                        do mapM_ setinjArg (getDets 0 (class_determiners ci) args)+                                   Just ci -> -- interface, set as injective+                                        do mapM_ setinjArg (getDets 0 (interface_determiners ci) args)                                         -- maybe we can solve more things now...                                            ulog <- getUnifyLog                                            probs <- get_probs@@ -1134,7 +1137,7 @@                                     _ -> return (n, False)                tcName tm | (P _ n _, _) <- unApply tm-                  = case lookupCtxt n (idris_classes ist) of+                  = case lookupCtxt n (idris_interfaces ist) of                          [_] -> True                          _ -> False               tcName _ = False@@ -1282,7 +1285,7 @@          elab' ina (Just fc') tm          script <- get_guess          fullyElaborated script-         solve -- eliminate the hole. Becuase there are no references, the script is only in the binding+         solve -- eliminate the hole. Because there are no references, the script is only in the binding          env <- get_env          runElabAction info ist (maybe fc' id fc) env script ns          solve@@ -1470,7 +1473,7 @@     fullApp x = x      insertScopedImps fc (Bind n (Pi im@(Just i) _ _) sc) xs-      | tcinstance i && not (toplevel_imp i)+      | tcimplementation i && not (toplevel_imp i)           = pimp n (PResolveTC fc) True : insertScopedImps fc sc xs       | not (toplevel_imp i)           = pimp n Placeholder True : insertScopedImps fc sc xs@@ -1735,25 +1738,25 @@ pruneByType _ t _ _ as = as  -- Could the name feasibly be the return type?--- If there is a type class constraint on the return type, and no instance+-- If there is an interface constraint on the return type, and no implementation -- in the environment or globally for that name, then no -- Otherwise, yes -- (FIXME: This isn't complete, but I'm leaving it here and coming back -- to it later - just returns 'var' for now. EB) isPlausible :: IState -> Bool -> Env -> Name -> Type -> Bool isPlausible ist var env n ty-    = let (hvar, classes) = collectConstraints [] [] ty in+    = let (hvar, interfaces) = collectConstraints [] [] ty in           case hvar of                Nothing -> True-               Just rth -> var -- trace (show (rth, classes)) var+               Just rth -> var -- trace (show (rth, interfaces)) var    where      collectConstraints :: [Name] -> [(Term, [Name])] -> Type ->                                      (Maybe Name, [(Term, [Name])])      collectConstraints env tcs (Bind n (Pi _ ty _) sc)          = let tcs' = case unApply ty of                            (P _ c _, _) ->-                               case lookupCtxtExact c (idris_classes ist) of-                                    Just tc -> ((ty, map fst (class_instances tc))+                               case lookupCtxtExact c (idris_interfaces ist) of+                                    Just tc -> ((ty, map fst (interface_implementations tc))                                                      : tcs)                                     Nothing -> tcs                            _ -> tcs@@ -1806,7 +1809,7 @@            = do autos <- get_autos                 mapM_ (solveAuto ist fn ambigok) (map (\(n, (fc, _)) -> (n, fc)) autos) --- Return true if the given error suggests a type class failure is+-- Return true if the given error suggests an interface failure is -- recoverable tcRecoverable :: ElabMode -> Err -> Bool tcRecoverable ERHS (CantResolve f g _) = f@@ -2316,17 +2319,17 @@            -- the rest happens in a bit            updateAux $ \e -> e { new_tyDecls = RDatatypeDefnInstrs n tyconTy ctors' : new_tyDecls e }            returnUnit-      | n == tacN "Prim__AddInstance"-      = do ~[cls, inst] <- tacTmArgs 2 tac args-           className <- reifyTTName cls-           instName <- reifyTTName inst-           updateAux $ \e -> e { new_tyDecls = RAddInstance className instName :+      | n == tacN "Prim__AddImplementation"+      = do ~[cls, impl] <- tacTmArgs 2 tac args+           interfaceName <- reifyTTName cls+           implName <- reifyTTName impl+           updateAux $ \e -> e { new_tyDecls = RAddImplementation interfaceName implName :                                                new_tyDecls e }            returnUnit       | n == tacN "Prim__IsTCName"       = do ~[n] <- tacTmArgs 1 tac args            n' <- reifyTTName n-           case lookupCtxtExact n' (idris_classes ist) of+           case lookupCtxtExact n' (idris_interfaces ist) of              Just _ -> fmap fst . checkClosed $ Var (sNS (sUN "True") ["Bool", "Prelude"])              Nothing -> fmap fst . checkClosed $ Var (sNS (sUN "False") ["Bool", "Prelude"])       | n == tacN "Prim__ResolveTC"@@ -2546,7 +2549,7 @@                    when autoSolve solveAll     runT Compute = compute     runT Trivial = do trivial' ist; when autoSolve solveAll-    runT TCInstance = runT (Exact (PResolveTC emptyFC))+    runT TCImplementation = runT (Exact (PResolveTC emptyFC))     runT (ProofSearch rec prover depth top psns hints)          = do proofSearch' ist rec False depth prover top fn psns hints               when autoSolve solveAll@@ -2816,12 +2819,12 @@             _ -> return ()          -- TODO: inaccessible -    RAddInstance className instName ->-      do -- The type class resolution machinery relies on a special-         logElab 2 $ "Adding elab script instance " ++ show instName ++-                    " for " ++ show className-         addInstance False True className instName-         addIBC (IBCInstance False True className instName)+    RAddImplementation interfaceName implName ->+      do -- The interface resolution machinery relies on a special+         logElab 2 $ "Adding elab script implementation " ++ show implName +++                     " for " ++ show interfaceName+         addImplementation False True interfaceName implName+         addIBC (IBCImplementation False True interfaceName implName)     RClausesInstrs n cs ->       do logElab 3 $ "Pattern-matching definition from tactics: " ++ show n          solveDeferred emptyFC n
src/Idris/Elab/Utils.hs view
@@ -185,15 +185,15 @@           dappname t = t  --- if 't' is a type class application, assume its arguments are injective+-- if 't' is an interface application, assume its arguments are injective pbinds :: IState -> Term -> ElabD () pbinds i (Bind n (PVar t) sc)     = do attack; patbind n          env <- get_env          case unApply (normalise (tt_ctxt i) env t) of-              (P _ c _, args) -> case lookupCtxt c (idris_classes i) of+              (P _ c _, args) -> case lookupCtxt c (idris_interfaces i) of                                    [] -> return ()-                                   _ -> -- type class, set as injective+                                   _ -> -- interface, set as injective                                         mapM_ setinjArg args               _ -> return ()          pbinds i sc@@ -270,7 +270,7 @@       isTCName n = mapMaybe getInjName args     | otherwise = []   where-    isTCName n = case lookupCtxtExact n (idris_classes i) of+    isTCName n = case lookupCtxtExact n (idris_interfaces i) of                       Just _ -> True                       _ -> False     getInjName t | (P _ x _, _) <- unApply t = Just x
src/Idris/ElabDecls.hs view
@@ -34,8 +34,8 @@ import Idris.Elab.Clause import Idris.Elab.Data import Idris.Elab.Record-import Idris.Elab.Class-import Idris.Elab.Instance+import Idris.Elab.Interface+import Idris.Elab.Implementation import Idris.Elab.Provider import Idris.Elab.RunElab import Idris.Elab.Transform@@ -271,13 +271,13 @@     newNS = n : namespace info     ninfo = info { namespace = newNS } -elabDecl' what info (PClass doc s f cs n nfc ps pdocs fds ds cn cd)+elabDecl' what info (PInterface doc s f cs n nfc ps pdocs fds ds cn cd)   | what /= EDefns-    = do logElab 1 $ "Elaborating class " ++ show n-         elabClass info (s { syn_params = [] }) doc f cs n nfc ps pdocs fds ds cn cd-elabDecl' what info (PInstance doc argDocs s f cs pnames acc fnopts n nfc ps pextra t expn ds)-    = do logElab 1 $ "Elaborating instance " ++ show n-         elabInstance info s doc argDocs what f cs pnames acc fnopts n nfc ps pextra t expn ds+    = do logElab 1 $ "Elaborating interface " ++ show n+         elabInterface info (s { syn_params = [] }) doc f cs n nfc ps pdocs fds ds cn cd+elabDecl' what info (PImplementation doc argDocs s f cs pnames acc fnopts n nfc ps pextra t expn ds)+    = do logElab 1 $ "Elaborating implementation " ++ show n+         elabImplementation info s doc argDocs what f cs pnames acc fnopts n nfc ps pextra t expn ds elabDecl' what info (PRecord doc rsyn fc opts name nfc ps pdocs fs cname cdoc csyn)     = do logElab 1 $ "Elaborating record " ++ show name          elabRecord info what doc rsyn fc opts name nfc ps pdocs fs cname cdoc csyn
src/Idris/Erasure.hs view
@@ -79,7 +79,7 @@     case startNames of       [] -> return []  -- no main -> not compiling -> reachability irrelevant       main  -> do-        ci  <- idris_classes <$> getIState+        ci  <- idris_interfaces <$> getIState         cg  <- idris_callgraph <$> getIState         opt <- idris_optimisation <$> getIState         used <- idris_erasureUsed <$> getIState@@ -170,7 +170,7 @@  -- | Build the dependency graph, starting the depth-first search from -- a list of Names.-buildDepMap :: Ctxt ClassInfo -> [(Name, Int)] -> [(Name, Int)] ->+buildDepMap :: Ctxt InterfaceInfo -> [(Name, Int)] -> [(Name, Int)] ->                Context -> [Name] -> Deps buildDepMap ci used externs ctx startNames     = addPostulates used $ dfs S.empty M.empty startNames@@ -252,8 +252,8 @@      -- get Deps for a Name     getDeps :: Name -> Deps-    getDeps (SN (WhereN i (SN (InstanceCtorN classN)) (MN i' field)))-        = M.empty  -- these deps are created when applying instance ctors+    getDeps (SN (WhereN i (SN (ImplementationCtorN interfaceN)) (MN i' field)))+        = M.empty  -- these deps are created when applying implementation ctors     getDeps n = case lookupDefExact n ctx of         Just def -> getDepsDef n def         Nothing  -> error $ "erasure checker: unknown reference: " ++ show n@@ -336,9 +336,9 @@         -- this is safe because it's certainly a patvar         varIdx = fromJust (viFunArg var) -        -- generate metamethod names, "n" is the instance ctor+        -- generate metamethod names, "n" is the implementation ctor         meth :: Int -> Maybe Name-        meth | SN (InstanceCtorN className) <- n = \j -> Just (mkFieldName n j)+        meth | SN (ImplementationCtorN interfaceName) <- n = \j -> Just (mkFieldName n j)              | otherwise = \j -> Nothing      -- Named variables -> DeBruijn variables -> Conds/guards -> Term -> Deps@@ -380,8 +380,8 @@     -- applications may add items to Cond     getDepsTerm vs bs cd app@(App _ _ _)         | (fun, args) <- unApply app = case fun of-            -- instance constructors -> create metamethod deps-            P (DCon _ _ _) ctorName@(SN (InstanceCtorN className)) _+            -- implementation constructors -> create metamethod deps+            P (DCon _ _ _) ctorName@(SN (ImplementationCtorN interfaceName)) _                 -> conditionalDeps ctorName args  -- regular data ctor stuff                     `union` unionMap (methodDeps ctorName) (zip [0..] args)  -- method-specific stuff @@ -486,7 +486,7 @@                 then length $ getArgTys (argTys !! i)                 else error $ "invalid field number " ++ show i ++ " for " ++ show ctorName -        | otherwise = error $ "unknown instance constructor: " ++ show ctorName+        | otherwise = error $ "unknown implementation constructor: " ++ show ctorName      getArity n = case lookupDefExact n ctx of         Just (CaseOp ci ty tys def tot cdefs) -> length tys
src/Idris/Error.hs view
@@ -121,7 +121,7 @@ warnDisamb ist (PAlternative _ _ tms) = mapM_ (warnDisamb ist) tms warnDisamb ist (PHidden tm) = warnDisamb ist tm warnDisamb ist (PType _) = return ()-warnDisamb ist (PUniverse _) = return ()+warnDisamb ist (PUniverse _ _) = return () warnDisamb ist (PGoal _ x _ y) = warnDisamb ist x >> warnDisamb ist y warnDisamb ist (PConstant _ _) = return () warnDisamb ist Placeholder = return ()@@ -133,7 +133,6 @@         wStep (DoLet _ _ _ x y) = warnDisamb ist x >> warnDisamb ist y         wStep (DoLetP _ x y) = warnDisamb ist x >> warnDisamb ist y warnDisamb ist (PIdiom _ x) = warnDisamb ist x-warnDisamb ist (PReturn _) = return () warnDisamb ist (PMetavar _ _) = return () warnDisamb ist (PProof tacs) = mapM_ (Foldable.mapM_ (warnDisamb ist)) tacs warnDisamb ist (PTactics tacs) = mapM_ (Foldable.mapM_ (warnDisamb ist)) tacs@@ -146,7 +145,7 @@           when (not (any (isIn d . fst) (ctxtAlist (tt_ctxt ist)))) $             ierror . Msg $               "Nothing found in namespace \"" ++-              intercalate "." (map T.unpack d) +++              intercalate "." (map T.unpack . reverse $ d) ++               "\"."         isIn d (NS _ ns) = isPrefixOf d ns         isIn d _ = False
src/Idris/IBC.hs view
@@ -49,7 +49,7 @@ import Debug.Trace  ibcVersion :: Word16-ibcVersion = 145+ibcVersion = 149  -- | When IBC is being loaded - we'll load different things (and omit -- different structures/definitions) depending on which phase we're in.@@ -63,12 +63,13 @@   , ibc_reachablenames         :: ![Name]   , ibc_imports                :: ![(Bool, FilePath)]   , ibc_importdirs             :: ![FilePath]+  , ibc_sourcedirs             :: ![FilePath]   , ibc_implicits              :: ![(Name, [PArg])]   , ibc_fixes                  :: ![FixDecl]   , ibc_statics                :: ![(Name, [Bool])]-  , ibc_classes                :: ![(Name, ClassInfo)]+  , ibc_interfaces             :: ![(Name, InterfaceInfo)]   , ibc_records                :: ![(Name, RecordInfo)]-  , ibc_instances              :: ![(Bool, Bool, Name, Name)]+  , ibc_implementations        :: ![(Bool, Bool, Name, Name)]   , ibc_dsls                   :: ![(Name, DSL)]   , ibc_datatypes              :: ![(Name, TypeInfo)]   , ibc_optimise               :: ![(Name, OptInfo)]@@ -115,7 +116,7 @@ !-}  initIBC :: IBCFile-initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] [] [] [] [] [] [] [] []+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] [] [] [] [] [] [] [] []  hasValidIBCVersion :: FilePath -> Idris Bool hasValidIBCVersion fp = do@@ -167,12 +168,13 @@                        makeEntry "sourcefile"  (sourcefile i),                        makeEntry "ibc_imports"  (ibc_imports i),                        makeEntry "ibc_importdirs"  (ibc_importdirs i),+                       makeEntry "ibc_sourcedirs"  (ibc_sourcedirs i),                        makeEntry "ibc_implicits"  (ibc_implicits i),                        makeEntry "ibc_fixes"  (ibc_fixes i),                        makeEntry "ibc_statics"  (ibc_statics i),-                       makeEntry "ibc_classes"  (ibc_classes i),+                       makeEntry "ibc_interfaces"  (ibc_interfaces i),                        makeEntry "ibc_records"  (ibc_records i),-                       makeEntry "ibc_instances"  (ibc_instances i),+                       makeEntry "ibc_implementations"  (ibc_implementations i),                        makeEntry "ibc_dsls"  (ibc_dsls i),                        makeEntry "ibc_datatypes"  (ibc_datatypes i),                        makeEntry "ibc_optimise"  (ibc_optimise i),@@ -266,16 +268,16 @@                    = case lookupCtxtExact n (idris_statics i) of                         Just v -> return f { ibc_statics = (n,v): ibc_statics f     }                         _ -> ifail "IBC write failed"-ibc i (IBCClass n) f-                   = case lookupCtxtExact n (idris_classes i) of-                        Just v -> return f { ibc_classes = (n,v): ibc_classes f     }+ibc i (IBCInterface n) f+                   = case lookupCtxtExact n (idris_interfaces i) of+                        Just v -> return f { ibc_interfaces = (n,v): ibc_interfaces f     }                         _ -> ifail "IBC write failed" ibc i (IBCRecord n) f                    = case lookupCtxtExact n (idris_records i) of                         Just v -> return f { ibc_records = (n,v): ibc_records f     }                         _ -> ifail "IBC write failed"-ibc i (IBCInstance int res n ins) f-                   = return f { ibc_instances = (int, res, n, ins) : ibc_instances f }+ibc i (IBCImplementation int res n ins) f+                   = return f { ibc_implementations = (int, res, n, ins) : ibc_implementations f } ibc i (IBCDSL n) f                    = case lookupCtxtExact n (idris_dsls i) of                         Just v -> return f { ibc_dsls = (n,v): ibc_dsls f     }@@ -291,6 +293,7 @@ ibc i (IBCKeyword n) f = return f { ibc_keywords = n : ibc_keywords f } ibc i (IBCImport n) f = return f { ibc_imports = n : ibc_imports f } ibc i (IBCImportDir n) f = return f { ibc_importdirs = n : ibc_importdirs f }+ibc i (IBCSourceDir n) f = return f { ibc_sourcedirs = n : ibc_sourcedirs f } ibc i (IBCObj tgt n) f = return f { ibc_objs = (tgt, n) : ibc_objs f } ibc i (IBCLib tgt n) f = return f { ibc_libs = (tgt, n) : ibc_libs f } ibc i (IBCCGFlag tgt n) f = return f { ibc_cgflags = (tgt, n) : ibc_cgflags f }@@ -362,20 +365,34 @@                 when (ver /= ibcVersion) $ do                                     logIBC 1 "ibc out of date"                                     let e = if ver < ibcVersion-                                            then " an earlier " else " a later "-                                    ifail $ "Incompatible ibc version.\nThis library was built with"-                                            ++ e ++ "version of Idris.\n" ++ "Please clean and rebuild."+                                            then "an earlier" else "a later"+                                    ldir <- runIO $ getIdrisLibDir+                                    let start = if ldir `L.isPrefixOf` fn+                                                  then "This external module"+                                                  else "This module"+                                    let end = case L.stripPrefix ldir fn of+                                                Nothing -> "Please clean and rebuild."++                                                Just ploc -> unwords ["Please reinstall:", L.head $ splitDirectories ploc]+                                    ifail $ unlines [ unwords ["Incompatible ibc version for:", show fn]+                                                    , unwords [start+                                                              , "was built with"+                                                              , e+                                                              , "version of Idris."]+                                                    , end+                                                    ]                 source <- getEntry "" "sourcefile" archive                 srcok <- runIO $ doesFileExist source                 when srcok $ timestampOlder source fn                 processImportDirs archive+                processSourceDirs archive                 processImports reexp phase archive                 processImplicits archive                 processInfix archive                 processStatics archive-                processClasses archive+                processInterfaces archive                 processRecords archive-                processInstances archive+                processImplementations archive                 processDSLs archive                 processDatatypes  archive                 processOptimise  archive@@ -479,6 +496,11 @@     fs <- getEntry [] "ibc_importdirs" ar     mapM_ addImportDir fs +processSourceDirs :: Archive -> Idris ()+processSourceDirs ar = do+    fs <- getEntry [] "ibc_sourcedirs" ar+    mapM_ addSourceDir fs+ processImports :: Bool -> IBCPhase -> Archive -> Idris () processImports reexp phase ar = do     fs <- getEntry [] "ibc_imports" ar@@ -523,18 +545,18 @@     mapM_ (\ (n, s) ->         updateIState (\i -> i { idris_statics = addDef n s (idris_statics i) })) ss -processClasses :: Archive -> Idris ()-processClasses ar = do-    cs <- getEntry [] "ibc_classes" ar+processInterfaces :: Archive -> Idris ()+processInterfaces ar = do+    cs <- getEntry [] "ibc_interfaces" ar     mapM_ (\ (n, c) -> do         i <- getIState-        -- Don't lose instances from previous IBCs, which+        -- Don't lose implementations from previous IBCs, which         -- could have loaded in any order-        let is = case lookupCtxtExact n (idris_classes i) of+        let is = case lookupCtxtExact n (idris_interfaces i) of                     Just (CI _ _ _ _ _ ins _) -> ins                     _ -> []-        let c' = c { class_instances = class_instances c ++ is }-        putIState (i { idris_classes = addDef n c' (idris_classes i) })) cs+        let c' = c { interface_implementations = interface_implementations c ++ is }+        putIState (i { idris_interfaces = addDef n c' (idris_interfaces i) })) cs  processRecords :: Archive -> Idris () processRecords ar = do@@ -542,10 +564,10 @@     mapM_ (\ (n, r) ->         updateIState (\i -> i { idris_records = addDef n r (idris_records i) })) rs -processInstances :: Archive -> Idris ()-processInstances ar = do-    cs <- getEntry [] "ibc_instances" ar-    mapM_ (\ (i, res, n, ins) -> addInstance i res n ins) cs+processImplementations :: Archive -> Idris ()+processImplementations ar = do+    cs <- getEntry [] "ibc_implementations" ar+    mapM_ (\ (i, res, n, ins) -> addImplementation i res n ins) cs  processDSLs :: Archive -> Idris () processDSLs ar = do@@ -1201,6 +1223,7 @@                                  put x1                 AutoHint -> putWord8 15                 PEGenerated -> putWord8 16+                StaticFn -> putWord8 17         get           = do i <- getWord8                case i of@@ -1223,6 +1246,7 @@                             return $ CExport x1                    15 -> return AutoHint                    16 -> return PEGenerated+                   17 -> return StaticFn                    _ -> error "Corrupted binary data for FnOpt"  instance Binary Fixity where@@ -1386,7 +1410,7 @@                                                 put x10                                                 put x11                                                 put x12-                PClass x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12+                PInterface x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12                                          -> do putWord8 7                                                put x1                                                put x2@@ -1400,7 +1424,7 @@                                                put x10                                                put x11                                                put x12-                PInstance x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 ->+                PImplementation x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 ->                   do putWord8 8                      put x1                      put x2@@ -1523,7 +1547,7 @@                            x10 <- get                            x11 <- get                            x12 <- get-                           return (PClass x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12)+                           return (PInterface x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12)                    8 -> do x1 <- get                            x2 <- get                            x3 <- get@@ -1539,7 +1563,7 @@                            x13 <- get                            x14 <- get                            x15 <- get-                           return (PInstance x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15)+                           return (PImplementation x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15)                    9 -> do x1 <- get                            x2 <- get                            return (PDSL x1 x2)@@ -1831,8 +1855,6 @@                 PIdiom x1 x2 -> do putWord8 27                                    put x1                                    put x2-                PReturn x1 -> do putWord8 28-                                 put x1                 PMetavar x1 x2 -> do putWord8 29                                      put x1                                      put x2@@ -1850,8 +1872,9 @@                 PDisamb x1 x2 -> do putWord8 37                                     put x1                                     put x2-                PUniverse x1 -> do putWord8 38-                                   put x1+                PUniverse x1 x2 -> do putWord8 38+                                      put x1+                                      put x2                 PRunElab x1 x2 x3 -> do putWord8 39                                         put x1                                         put x2@@ -1983,8 +2006,6 @@                    27 -> do x1 <- get                             x2 <- get                             return (PIdiom x1 x2)-                   28 -> do x1 <- get-                            return (PReturn x1)                    29 -> do x1 <- get                             x2 <- get                             return (PMetavar x1 x2)@@ -2003,7 +2024,8 @@                             x2 <- get                             return (PDisamb x1 x2)                    38 -> do x1 <- get-                            return (PUniverse x1)+                            x2 <- get+                            return (PUniverse x1 x2)                    39 -> do x1 <- get                             x2 <- get                             x3 <- get@@ -2119,7 +2141,7 @@                                         put x1                                         put x2                                         put x3-                TCInstance -> putWord8 31+                TCImplementation -> putWord8 31                 GoalType x1 x2 -> do putWord8 32                                      put x1                                      put x2@@ -2200,7 +2222,7 @@                             x2 <- get                             x3 <- get                             return (LetTacTy x1 x2 x3)-                   31 -> return TCInstance+                   31 -> return TCImplementation                    32 -> do x1 <- get                             x2 <- get                             return (GoalType x1 x2)@@ -2331,7 +2353,7 @@                    _ -> error "Corrupted binary data for PArg'"  -instance Binary ClassInfo where+instance Binary InterfaceInfo where         put (CI x1 x2 x3 x4 x5 _ x6)           = do put x1                put x2@@ -2426,7 +2448,7 @@                    _ -> error "Corrupted binary data for Syntax"  instance (Binary t) => Binary (DSL' t) where-        put (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)+        put (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)           = do put x1                put x2                put x3@@ -2436,7 +2458,6 @@                put x7                put x8                put x9-               put x10         get           = do x1 <- get                x2 <- get@@ -2447,8 +2468,7 @@                x7 <- get                x8 <- get                x9 <- get-               x10 <- get-               return (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)+               return (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)  instance Binary SSymbol where         put x
src/Idris/IdrisDoc.hs view
@@ -165,7 +165,7 @@     filterContents p (NsInfo md ns) = NsInfo md (filter p ns)     updateContents f x = x { nsContents = f (nsContents x) } --- | Removes loose class methods and data constructors,+-- | Removes loose interface methods and data constructors, --   leaving them documented only under their parent. removeOrphans :: [NsItem] -- ^ List to remove orphans from               -> [NsItem] -- ^ Orphan-free list@@ -173,9 +173,9 @@   let children = S.fromList $ concatMap (names . (\(_, d, _) -> d)) list   in  filter ((flip S.notMember children) . (\(n, _, _) -> n)) list -  where names (Just (DataDoc _ fds))              = map (\(FD n _ _ _ _) -> n) fds-        names (Just (ClassDoc _ _ fds _ _ _ _ c)) = map (\(FD n _ _ _ _) -> n) fds ++ map (\(FD n _ _ _ _) -> n) (maybeToList c)-        names _                                   = []+  where names (Just (DataDoc _ fds))                  = map (\(FD n _ _ _ _) -> n) fds+        names (Just (InterfaceDoc _ _ fds _ _ _ _ c)) = map (\(FD n _ _ _ _) -> n) fds ++ map (\(FD n _ _ _ _) -> n) (maybeToList c)+        names _                                       = []  -- | Whether a Name names something which should be documented filterName :: Name -- ^ Name to check@@ -222,14 +222,14 @@       names  = concatMap (extractPTermNames) ts   in  S.map getNs $ S.fromList names -  where getFunDocs (FunDoc f)                  = [f]-        getFunDocs (DataDoc f fs)              = f:fs-        getFunDocs (ClassDoc _ _ fs _ _ _ _ _) = fs-        getFunDocs (RecordDoc _ _ f fs _)      = f:fs-        getFunDocs (NamedInstanceDoc _ fd)     = [fd]-        getFunDocs (ModDoc _ _)                = []-        types (FD _ _ args t _)                = t:(map second args)-        second (_, x, _, _)                    = x+  where getFunDocs (FunDoc f)                      = [f]+        getFunDocs (DataDoc f fs)                  = f:fs+        getFunDocs (InterfaceDoc _ _ fs _ _ _ _ _) = fs+        getFunDocs (RecordDoc _ _ f fs _)          = f:fs+        getFunDocs (NamedImplementationDoc _ fd)         = [fd]+        getFunDocs (ModDoc _ _)                    = []+        types (FD _ _ args t _)                    = t:(map second args)+        second (_, x, _, _)                        = x   -- | Returns an NsDict of containing all known namespaces and their contents@@ -577,13 +577,13 @@   -- | Generates HTML documentation for any Docs type---   TODO: Generate actual signatures for typeclasses+--   TODO: Generate actual signatures for interfaces createOtherDoc :: IState -- ^ Needed to determine the types of names                -> Docs   -- ^ Namespace item to generate HTML block for                -> H.Html -- ^ Resulting HTML createOtherDoc ist (FunDoc fd)                = createFunDoc ist fd -createOtherDoc ist (ClassDoc n docstring fds _ _ _ _ c) = do+createOtherDoc ist (InterfaceDoc n docstring fds _ _ _ _ c) = do   H.dt ! (A.id $ toValue $ show n) $ do     H.span ! class_ "word" $ do "interface"; nbsp     H.span ! class_ "name type"@@ -643,7 +643,7 @@           H.dt $ toHtml $ show name           H.dd $ Docstrings.renderHtml docstring -createOtherDoc ist (NamedInstanceDoc _ fd) = createFunDoc ist fd+createOtherDoc ist (NamedImplementationDoc _ fd) = createFunDoc ist fd  createOtherDoc ist (ModDoc _  docstring) = do   Docstrings.renderHtml docstring
src/Idris/Imports.hs view
@@ -48,7 +48,7 @@ ibcPath ibcsd use_ibcsd fp = let (d_fp, n_fp) = splitFileName fp                                  d = if (not use_ibcsd) || ibcsd == ""                                      then d_fp-                                     else d_fp </> ibcsd+                                     else ibcsd </> d_fp                                  n = dropExtension n_fp                              in d </> n <.> "ibc" @@ -71,9 +71,6 @@                                 ibc <- runIO $ doesFileExist' ibcp                                 idr  <- runIO $ doesFileExist' idrp                                 lidr <- runIO $ doesFileExist' lidrp---                              when idr $ putStrLn $ idrp ++ " ok"---                              when lidr $ putStrLn $ lidrp ++ " ok"---                              when ibc $ putStrLn $ ibcp ++ " ok"                                 let isrc = if lidr                                            then LIDR lidrp                                            else IDR idrp
+ src/Idris/Info.hs view
@@ -0,0 +1,77 @@+{-|+Module      : Idris.Info+Description : Get information about Idris.+Copyright   : 2016 The Idris Community+License     : BSD3+Maintainer  : The Idris Community.+-}+module Idris.Info+  ( getIdrisLibDir+  , getIdrisFlagsLib+  , getIdrisFlagsInc+  , getIdrisFlagsEnv+  , getIdrisCC+  , getIdrisVersion+  , getIdrisVersionNoGit+  , getIdrisUserDataDir+  , getIdrisInitScript+  , getIdrisHistoryFile+  , getIdrisInstalledPackages+  , getIdrisLoggingCategories+  ) where++import System.FilePath+import System.Directory+import Data.Version++import Idris.Imports (installedPackages)+import Idris.AbsSyntax (loggingCatsStr)++import qualified IRTS.System as S++import Version_idris (gitHash)++import Paths_idris++getIdrisLibDir :: IO String+getIdrisLibDir = S.getIdrisLibDir++getIdrisFlagsLib :: IO [String]+getIdrisFlagsLib = S.getLibFlags++getIdrisFlagsInc :: IO [String]+getIdrisFlagsInc = S.getIncFlags++getIdrisFlagsEnv :: IO [String]+getIdrisFlagsEnv = S.getEnvFlags++getIdrisCC :: IO String+getIdrisCC = S.getCC++getIdrisVersion = showVersion S.version ++ suffix+  where+    suffix = if gitHash =="" then "" else "-" ++ gitHash++getIdrisVersionNoGit = S.version+++-- | Get the platform-specific, user-specific Idris dir+getIdrisUserDataDir :: IO FilePath+getIdrisUserDataDir = getAppUserDataDirectory "idris"++-- | Locate the platform-specific location for the init script+getIdrisInitScript :: IO FilePath+getIdrisInitScript = do+  idrisDir <- getIdrisUserDataDir+  return $ idrisDir </> "repl" </> "init"++getIdrisHistoryFile :: IO FilePath+getIdrisHistoryFile = do+  udir <- getIdrisUserDataDir+  return (udir </> "repl" </> "history")++getIdrisInstalledPackages :: IO [String]+getIdrisInstalledPackages = installedPackages++getIdrisLoggingCategories :: IO [String]+getIdrisLoggingCategories = return $ words loggingCatsStr
+ src/Idris/Info/Show.hs view
@@ -0,0 +1,95 @@+module Idris.Info.Show where++import System.Exit++import Idris.Info++showIdrisFlagsLibs :: IO ()+showIdrisFlagsLibs = do+  libFlags <- getIdrisFlagsLib+  putStrLn $ unwords libFlags++showExitIdrisFlagsLibs :: IO ()+showExitIdrisFlagsLibs = do+  showIdrisFlagsLibs+  exitSuccess++showIdrisLibDir :: IO ()+showIdrisLibDir = do+  ldir <- getIdrisLibDir+  putStrLn ldir++showExitIdrisLibDir :: IO ()+showExitIdrisLibDir = do+  showIdrisLibDir+  exitSuccess++showIdrisFlagsInc :: IO ()+showIdrisFlagsInc = do+  incFlags <- getIdrisFlagsInc+  putStrLn $ unwords incFlags++showExitIdrisFlagsInc :: IO ()+showExitIdrisFlagsInc = do+  showIdrisFlagsInc+  exitSuccess++-- | List idris packages installed+showIdrisInstalledPackages :: IO ()+showIdrisInstalledPackages = do+  ipkgs <- getIdrisInstalledPackages+  mapM_ putStrLn ipkgs++showExitIdrisInstalledPackages :: IO ()+showExitIdrisInstalledPackages = do+  showIdrisInstalledPackages+  exitSuccess++showIdrisLoggingCategories :: IO ()+showIdrisLoggingCategories = do+  cs <- getIdrisLoggingCategories+  mapM_ putStrLn cs++showExitIdrisLoggingCategories :: IO ()+showExitIdrisLoggingCategories = do+  showIdrisLoggingCategories+  exitSuccess++showIdrisInfo :: IO ()+showIdrisInfo = do+  putStrLn $ unwords ["Idris", getIdrisVersion]++  ps <- getIdrisInstalledPackages+  putStrLn $ unwords (["Installed Packages:"] ++ ps)++  cs <- getIdrisLoggingCategories+  putStrLn $ unwords (["Logging Categories:"] ++ cs)++  putStrLn "Paths:"+  ldir <- getIdrisLibDir+  udir <- getIdrisUserDataDir+  putStrLn $ unwords ["-", "Library Dir:", ldir]+  putStrLn $ unwords ["-", "User Dir:",    udir]++  putStrLn "Flags:"+  lflag <- getIdrisFlagsLib+  iflag <- getIdrisFlagsInc+  eflag <- getIdrisFlagsEnv+  putStrLn $ unwords (["-", "Libraries:", show lflag])+  putStrLn $ unwords (["-", "Includes:",  show iflag])+  putStrLn $ unwords (["-", "Env:",       show eflag])++  cc <- getIdrisCC+  putStrLn $ unwords ["CC:", cc]++  putStrLn "Files:"+  hfile   <- getIdrisHistoryFile+  iscript <- getIdrisInitScript+  putStrLn $ unwords (["-", "History File:",    hfile])+  putStrLn $ unwords (["-", "REPL Init Script", iscript])+++showExitIdrisInfo :: IO ()+showExitIdrisInfo = do+  showIdrisInfo+  exitSuccess
src/Idris/Interactive.hs view
@@ -81,7 +81,7 @@           else iPrintResult cl   where     getIndent i n [] = 0-    getIndent i n xs | take 9 xs == "instance " = i+    getIndent i n xs | take 9 xs == "implementation " = i     getIndent i n xs | take (length n) xs == n = i     getIndent i n (x : xs) = getIndent (i + 1) n xs @@ -349,10 +349,10 @@         if (not isProv) then do             let skip = guessImps i (tt_ctxt i) mty             let impty = stripMNBind skip margs (delab i mty)-            let classes = guessClasses i (tt_ctxt i) [] (allNamesIn impty) mty+            let interfaces = guessInterfaces i (tt_ctxt i) [] (allNamesIn impty) mty              let lem = show n ++ " : " ++-                            constraints i classes mty +++                            constraints i interfaces mty ++                             showTmOpts (defaultPPOption { ppopt_pinames = True })                                        impty             let lem_app = guessBrackets False tyline (show n) (show n ++ appArgs skip margs mty)@@ -426,7 +426,7 @@         -- Guess which binders should be implicits in the generated lemma.         -- Make them implicit if they appear guarded by a top level constructor,         -- or at the top level themselves.-        -- Also, make type class instances implicit+        -- Also, make interface implementations implicit         guessImps :: IState -> Context -> Term -> [Name]         -- machine names aren't lifted         guessImps ist ctxt (Bind n@(MN _ _) (Pi _ ty _) sc)@@ -434,7 +434,7 @@         guessImps ist ctxt (Bind n (Pi _ ty _) sc)            | guarded ctxt n (substV (P Bound n Erased) sc)                 = n : guessImps ist ctxt sc-           | isClass ist ty+           | isInterface ist ty                 = n : guessImps ist ctxt sc            | paramty ty = n : guessImps ist ctxt sc            | ignoreName n = n : guessImps ist ctxt sc@@ -450,13 +450,13 @@                             "_aX" -> True                             _ -> False -        guessClasses :: IState -> Context -> [Name] -> [Name] -> Term -> [Name]-        guessClasses ist ctxt binders usednames (Bind n (Pi _ ty _) sc)-           | isParamClass ist ty && any (\x -> elem x usednames)-                                        (paramNames binders ty)-                = n : guessClasses ist ctxt (n : binders) usednames sc-           | otherwise = guessClasses ist ctxt (n : binders) usednames sc-        guessClasses ist ctxt _ _ _ = []+        guessInterfaces :: IState -> Context -> [Name] -> [Name] -> Term -> [Name]+        guessInterfaces ist ctxt binders usednames (Bind n (Pi _ ty _) sc)+           | isParamInterface ist ty && any (\x -> elem x usednames)+                                            (paramNames binders ty)+                = n : guessInterfaces ist ctxt (n : binders) usednames sc+           | otherwise = guessInterfaces ist ctxt (n : binders) usednames sc+        guessInterfaces ist ctxt _ _ _ = []          paramNames bs ty | (P _ _ _, args) <- unApply ty              = vnames args@@ -464,16 +464,16 @@                 vnames (V i : xs) | i < length bs = bs !! i : vnames xs                 vnames (_ : xs) = vnames xs -        isClass ist t+        isInterface ist t            | (P _ n _, args) <- unApply t-                = case lookupCtxtExact n (idris_classes ist) of+                = case lookupCtxtExact n (idris_interfaces ist) of                        Just _ -> True                        _ -> False            | otherwise = False -        isParamClass ist t+        isParamInterface ist t            | (P _ n _, args) <- unApply t-                = case lookupCtxtExact n (idris_classes ist) of+                = case lookupCtxtExact n (idris_interfaces ist) of                        Just _ -> any isV args                        _ -> False            | otherwise = False
+ src/Idris/Main.hs view
@@ -0,0 +1,295 @@+{-|+Module      : Idris.REPL+Description : Main function to decide Idris' mode of use.+License     : BSD3+Maintainer  : The Idris Community.+-}+module Idris.Main+  ( idrisMain+  , idris+  , runMain+  , runClient -- taken from Idris.REPL.+  , loadInputs -- taken from Idris.ModeCommon+  ) where++import Idris.AbsSyntax+import Idris.ModeCommon+import Idris.REPL.Parser+import Idris.Error+import Idris.IBC+import Idris.Parser hiding (indent)+import Idris.Output++import Idris.REPL.Commands+import Idris.REPL++import Idris.ElabDecls+import Idris.Elab.Value+import Idris.Elab.Term+import Idris.Info++import Util.System++import Idris.Core.Execute (execute)+import Idris.Core.TT++import IRTS.CodegenCommon++import Control.Category+import Prelude hiding ((<$>), (.), id)++import Text.Trifecta.Result(Result(..), ErrInfo(..))++import System.Console.Haskeline as H+import System.FilePath+import System.Exit+import System.Directory+import System.IO+import Control.Monad+import Control.Monad.Trans.Except (runExceptT)+import Control.Monad.Trans.State.Strict (execStateT)+import Control.Monad.Trans ( lift )+import Data.Maybe+import Control.DeepSeq++++-- | How to run Idris programs.+runMain :: Idris () -> IO ()+runMain prog = do res <- runExceptT $ execStateT prog idrisInit+                  case res of+                       Left err -> putStrLn $ "Uncaught error: " ++ show err+                       Right _ -> return ()+++-- | The main function of Idris that when given a set of Options will+-- launch Idris into the desired interaction mode either: REPL;+-- Compiler; Script execution; or IDE Mode.+idrisMain :: [Opt] -> Idris ()+idrisMain opts =+  do   mapM_ setWidth (opt getConsoleWidth opts)+       let inputs = opt getFile opts+       let quiet = Quiet `elem` opts+       let nobanner = NoBanner `elem` opts+       let idesl = Idemode `elem` opts || IdemodeSocket `elem` opts+       let runrepl = not (NoREPL `elem` opts)+       let verbose = runrepl || Verbose `elem` opts+       let output = opt getOutput opts+       let ibcsubdir = opt getIBCSubDir opts+       let importdirs = opt getImportDir opts+       let sourcedirs = opt getSourceDir opts+       setSourceDirs sourcedirs+       let bcs = opt getBC opts+       let pkgdirs = opt getPkgDir opts+       -- Set default optimisations+       let optimise = case opt getOptLevel opts of+                        [] -> 2+                        xs -> last xs++       setOptLevel optimise+       let outty = case opt getOutputTy opts of+                     [] -> if Interface `elem` opts then+                              Object else Executable+                     xs -> last xs+       let cgn = case opt getCodegen opts of+                   [] -> Via IBCFormat "c"+                   xs -> last xs+       let cgFlags = opt getCodegenArgs opts++       -- Now set/unset specifically chosen optimisations+       let os = opt getOptimisation opts++       mapM_ processOptimisation os++       script <- case opt getExecScript opts of+                   []     -> return Nothing+                   x:y:xs -> do iputStrLn "More than one interpreter expression found."+                                runIO $ exitWith (ExitFailure 1)+                   [expr] -> return (Just expr)+       let immediate = opt getEvalExpr opts+       let port = case getPort opts of+                    Nothing -> ListenPort defaultPort+                    Just p  -> p++       when (DefaultTotal `elem` opts) $ do i <- getIState+                                            putIState (i { default_total = DefaultCheckingTotal })+       tty <- runIO isATTY+       setColourise $ not quiet && last (tty : opt getColour opts)++++       mapM_ addLangExt (opt getLanguageExt opts)+       setREPL runrepl+       setQuiet (quiet || isJust script || not (null immediate))+       setVerbose verbose+       setCmdLine opts+       setOutputTy outty+       setNoBanner nobanner+       setCodegen cgn+       mapM_ (addFlag cgn) cgFlags+       mapM_ makeOption opts+       -- if we have the --bytecode flag, drop into the bytecode assembler+       case bcs of+         [] -> return ()+         xs -> return () -- runIO $ mapM_ bcAsm xs+       case ibcsubdir of+         [] -> setIBCSubDir ""+         (d:_) -> setIBCSubDir d+       setImportDirs importdirs++       setNoBanner nobanner++       when (not (NoBasePkgs `elem` opts)) $ do+           addPkgDir "prelude"+           addPkgDir "base"+       mapM_ addPkgDir pkgdirs+       elabPrims+       when (not (NoBuiltins `elem` opts)) $ do x <- loadModule "Builtins" (IBC_REPL True)+                                                addAutoImport "Builtins"+                                                return ()+       when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude" (IBC_REPL True)+                                               addAutoImport "Prelude"+                                               return ()+       when (runrepl && not idesl) initScript++       nobanner <- getNoBanner++       when (runrepl &&+             not quiet &&+             not idesl &&+             not (isJust script) &&+             not nobanner &&+             null immediate) $+         iputStrLn banner++       orig <- getIState++       mods <- if idesl then return [] else loadInputs inputs Nothing+       let efile = case inputs of+                        [] -> ""+                        (f:_) -> f++       runIO $ hSetBuffering stdout LineBuffering++       ok <- noErrors+       when ok $ case output of+                    [] -> return ()+                    (o:_) -> idrisCatch (process "" (Compile cgn o))+                               (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)++       case immediate of+         [] -> return ()+         exprs -> do setWidth InfinitelyWide+                     mapM_ (\str -> do ist <- getIState+                                       c <- colourise+                                       case parseExpr ist str of+                                         Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)+                                                                       runIO $ exitWith (ExitFailure 1)+                                         Success e -> process "" (Eval e))+                           exprs+                     runIO exitSuccess+++       case script of+         Nothing -> return ()+         Just expr -> execScript expr++       -- Create Idris data dir + repl history and config dir+       idrisCatch (do dir <- runIO $ getIdrisUserDataDir+                      exists <- runIO $ doesDirectoryExist dir+                      unless exists $ logLvl 1 ("Creating " ++ dir)+                      runIO $ createDirectoryIfMissing True (dir </> "repl"))+         (\e -> return ())++       historyFile <- runIO $ getIdrisHistoryFile++       when ok $ case opt getPkgIndex opts of+                      (f : _) -> writePkgIndex f+                      _ -> return ()++       when (runrepl && not idesl) $ do+--          clearOrigPats+         case port of+           DontListen -> return ()+           ListenPort port' -> startServer port' orig mods+         runInputT (replSettings (Just historyFile)) $ repl (force orig) mods efile+       let idesock = IdemodeSocket `elem` opts+       when (idesl) $ idemodeStart idesock orig inputs+       ok <- noErrors+       when (not ok) $ runIO (exitWith (ExitFailure 1))+  where+    makeOption (OLogging i)  = setLogLevel i+    makeOption (OLogCats cs) = setLogCats cs+    makeOption TypeCase      = setTypeCase True+    makeOption TypeInType    = setTypeInType True+    makeOption NoCoverage    = setCoverage False+    makeOption ErrContext    = setErrContext True+    makeOption _             = return ()++    processOptimisation :: (Bool,Optimisation) -> Idris ()+    processOptimisation (True,  p) = addOptimise p+    processOptimisation (False, p) = removeOptimise p++    addPkgDir :: String -> Idris ()+    addPkgDir p = do ddir <- runIO getIdrisLibDir+                     addImportDir (ddir </> p)+                     addIBC (IBCImportDir (ddir </> p))++++-- | Invoke as if from command line. It is an error if there are+-- unresolved totality problems.+idris :: [Opt] -> IO (Maybe IState)+idris opts = do res <- runExceptT $ execStateT totalMain idrisInit+                case res of+                  Left err -> do putStrLn $ pshow idrisInit err+                                 return Nothing+                  Right ist -> return (Just ist)+    where totalMain = do idrisMain opts+                         ist <- getIState+                         case idris_totcheckfail ist of+                           ((fc, msg):_) -> ierror . At fc . Msg $ "Could not build: "++  msg+                           [] -> return ()+++-- | Execute the provided Idris expression.+execScript :: String -> Idris ()+execScript expr = do i <- getIState+                     c <- colourise+                     case parseExpr i expr of+                          Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)+                                                        runIO $ exitWith (ExitFailure 1)+                          Success term -> do ctxt <- getContext+                                             (tm, _) <- elabVal (recinfo (fileFC "toplevel")) ERHS term+                                             res <- execute tm+                                             runIO $ exitSuccess++-- | Run the initialisation script+initScript :: Idris ()+initScript = do script <- runIO $ getIdrisInitScript+                idrisCatch (do go <- runIO $ doesFileExist script+                               when go $ do+                                 h <- runIO $ openFile script ReadMode+                                 runInit h+                                 runIO $ hClose h)+                           (\e -> iPrintError $ "Error reading init file: " ++ show e)+    where runInit :: Handle -> Idris ()+          runInit h = do eof <- lift . lift $ hIsEOF h+                         ist <- getIState+                         unless eof $ do+                           line <- runIO $ hGetLine h+                           script <- runIO $ getIdrisInitScript+                           c <- colourise+                           processLine ist line script c+                           runInit h+          processLine i cmd input clr =+              case parseCmd i input cmd of+                   Failure (ErrInfo err _) -> runIO $ print (fixColour clr err)+                   Success (Right Reload) -> iPrintError "Init scripts cannot reload the file"+                   Success (Right (Load f _)) -> iPrintError "Init scripts cannot load files"+                   Success (Right (ModImport f)) -> iPrintError "Init scripts cannot import modules"+                   Success (Right Edit) -> iPrintError "Init scripts cannot invoke the editor"+                   Success (Right Proofs) -> proofs i+                   Success (Right Quit) -> iPrintError "Init scripts cannot quit Idris"+                   Success (Right cmd ) -> process [] cmd+                   Success (Left err) -> runIO $ print err
+ src/Idris/ModeCommon.hs view
@@ -0,0 +1,190 @@+{-|+Module      : Idris.ModeCommon+Description : Common utilities used by all modes.+License     : BSD3+Maintainer  : The Idris Community.+-}+module Idris.ModeCommon where+++import Idris.AbsSyntax+import Idris.Erasure+import Idris.Error+import Idris.IBC+import Idris.Delaborate+import Idris.Parser hiding (indent)+import Idris.Chaser+import Idris.Imports+import Idris.Output+import Idris.Info+import Idris.Core.TT++import IRTS.Exports++import Control.Category+import Prelude hiding ((<$>), (.), id)++import System.Directory+import Control.Monad+import Control.Monad.Trans.State.Strict (get)+import Network.Socket (PortNumber)+import Data.Maybe+import Data.List hiding (group)+import Control.DeepSeq+++defaultPort :: PortNumber+defaultPort = fromIntegral 4294+++loadInputs :: [FilePath] -> Maybe Int -> Idris [FilePath]+loadInputs inputs toline -- furthest line to read in input source files+  = idrisCatch+       (do ist <- getIState+           -- if we're in --check and not outputting anything, don't bother+           -- loading, as it gets really slow if there's lots of modules in+           -- a package (instead, reload all at the end to check for+           -- consistency only)+           opts <- getCmdLine++           let loadCode = case opt getOutput opts of+                               [] -> not (NoREPL `elem` opts)+                               _ -> True++           -- For each ifile list, check it and build ibcs in the same clean IState+           -- so that they don't interfere with each other when checking++           importlists <- getImports [] inputs++           logParser 1 (show (map (\(i,m) -> (i, map import_path m)) importlists))++           let ninputs = zip [1..] inputs+           ifiles <- mapWhileOK (\(num, input) ->+                do putIState ist+                   modTree <- buildTree+                                   (map snd (take (num-1) ninputs))+                                   importlists+                                   input+                   let ifiles = getModuleFiles modTree+                   logParser 1 ("MODULE TREE : " ++ show modTree)+                   logParser 1 ("RELOAD: " ++ show ifiles)+                   when (not (all ibc ifiles) || loadCode) $+                        tryLoad False IBC_Building (filter (not . ibc) ifiles)+                   -- return the files that need rechecking+                   return (input, ifiles))+                      ninputs+           inew <- getIState+           let tidata = idris_tyinfodata inew+           -- If it worked, load the whole thing from all the ibcs together+           case errSpan inew of+              Nothing ->+                do putIState $!! ist { idris_tyinfodata = tidata }+                   ibcfiles <- mapM findNewIBC (nub (concatMap snd ifiles))+--                    logLvl 0 $ "Loading from " ++ show ibcfiles+                   tryLoad True (IBC_REPL True) (mapMaybe id ibcfiles)+              _ -> return ()+           exports <- findExports++           case opt getOutput opts of+               [] -> performUsageAnalysis (getExpNames exports) -- interactive+               _  -> return []  -- batch, will be checked by the compiler++           return (map fst ifiles))+        (\e -> do i <- getIState+                  case e of+                    At f e' -> do setErrSpan f+                                  iWarn f $ pprintErr i e'+                    ProgramLineComment -> return () -- fail elsewhere+                    _ -> do setErrSpan emptyFC -- FIXME! Propagate it+                                               -- Issue #1576 on the issue tracker.+                                               -- https://github.com/idris-lang/Idris-dev/issues/1576+                            iWarn emptyFC $ pprintErr i e+                  return [])+   where -- load all files, stop if any fail+         tryLoad :: Bool -> IBCPhase -> [IFileType] -> Idris ()+         tryLoad keepstate phase [] = warnTotality >> return ()+         tryLoad keepstate phase (f : fs)+                 = do ist <- getIState+                      let maxline+                            = case toline of+                                Nothing -> Nothing+                                Just l -> case f of+                                            IDR fn -> if any (fmatch fn) inputs+                                                         then Just l+                                                         else Nothing+                                            LIDR fn -> if any (fmatch fn) inputs+                                                          then Just l+                                                          else Nothing+                                            _ -> Nothing+                      loadFromIFile True phase f maxline+                      inew <- getIState+                      -- FIXME: Save these in IBC to avoid this hack! Need to+                      -- preserve it all from source inputs+                      --+                      -- Issue #1577 on the issue tracker.+                      --     https://github.com/idris-lang/Idris-dev/issues/1577+                      let tidata = idris_tyinfodata inew+                      let patdefs = idris_patdefs inew+                      ok <- noErrors+                      if ok then+                            -- The $!! here prevents a space leak on reloading.+                            -- This isn't a solution - but it's a temporary stopgap.+                            -- See issue #2386+                            do when (not keepstate) $ putIState $!! ist+                               ist <- getIState+                               putIState $!! ist { idris_tyinfodata = tidata,+                                                   idris_patdefs = patdefs }+                               tryLoad keepstate phase fs+                          else warnTotality++         ibc (IBC _ _) = True+         ibc _ = False++         fmatch ('.':'/':xs) ys = fmatch xs ys+         fmatch xs ('.':'/':ys) = fmatch xs ys+         fmatch xs ys = xs == ys++         findNewIBC :: IFileType -> Idris (Maybe IFileType)+         findNewIBC i@(IBC _ _) = return (Just i)+         findNewIBC s@(IDR f) = do ist <- get+                                   ibcsd <- valIBCSubDir ist+                                   let ibc = ibcPathNoFallback ibcsd f+                                   ok <- runIO $ doesFileExist ibc+                                   if ok then return (Just (IBC ibc s))+                                         else return Nothing+         findNewIBC s@(LIDR f) = do ist <- get+                                    ibcsd <- valIBCSubDir ist+                                    let ibc = ibcPathNoFallback ibcsd f+                                    ok <- runIO $ doesFileExist ibc+                                    if ok then return (Just (IBC ibc s))+                                          else return Nothing++         -- Like mapM, but give up when there's an error+         mapWhileOK f [] = return []+         mapWhileOK f (x : xs) = do x' <- f x+                                    ok <- noErrors+                                    if ok then do xs' <- mapWhileOK f xs+                                                  return (x' : xs')+                                          else return [x']++banner = "     ____    __     _                                          \n" +++         "    /  _/___/ /____(_)____                                     \n" +++         "    / // __  / ___/ / ___/     Version " ++ getIdrisVersion ++ "\n" +++         "  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/      \n" +++         " /___/\\__,_/_/  /_/____/       Type :? for help               \n" +++         "\n" +++         "Idris is free software with ABSOLUTELY NO WARRANTY.            \n" +++         "For details type :warranty."++warranty = "\n"                                                                          +++           "\t THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY  \n" +++           "\t EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     \n" +++           "\t IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR    \n" +++           "\t PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE   \n" +++           "\t LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR   \n" +++           "\t CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  \n" +++           "\t SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       \n" +++           "\t BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n" +++           "\t WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  \n" +++           "\t OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n" +++           "\t IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
src/Idris/Output.hs view
@@ -21,6 +21,7 @@  import Util.Pretty import Util.ScreenSize (getScreenWidth)+import Util.System (isATTY)  import Control.Monad.Trans.Except (ExceptT (ExceptT), runExceptT) @@ -67,13 +68,14 @@                let ideMode = case idris_outputmode ist of                                 IdeMode _ _ -> True                                 _            -> False+               tty <- runIO isATTY                case w of                  InfinitelyWide -> return $ renderPretty 1.0 1000000000 d                  ColsWide n -> return $                                if n < 1                                  then renderPretty 1.0 1000000000 d                                  else renderPretty 0.8 n d-                 AutomaticWidth | ideMode  -> return $ renderPretty 1.0 80 d+                 AutomaticWidth | ideMode || not tty -> return $ renderPretty 1.0 80 d                                 | otherwise -> do width <- runIO getScreenWidth                                                   return $ renderPretty 0.8 width d 
src/Idris/Package.hs view
@@ -37,6 +37,7 @@ import Idris.Output import Idris.Imports import Idris.Error (ifail)+import Idris.Main (idrisMain, idris)  import Idris.Package.Common import Idris.Package.Parser@@ -63,7 +64,10 @@ buildPkg copts warnonly (install, fp) = do   pkgdesc <- parseDesc fp   dir <- getCurrentDirectory-  let idx = PkgIndex (pkgIndex (pkgname pkgdesc))+  let idx' = pkgIndex $ pkgname pkgdesc+      idx  = PkgIndex $ case opt getIBCSubDir copts of+        (ibcsubdir:_) -> ibcsubdir </> idx'+        []            -> idx'   oks <- mapM (testLib warnonly (pkgname pkgdesc)) (libdeps pkgdesc)   when (and oks) $ do     m_ist <- inPkgDir pkgdesc $ do@@ -212,9 +216,9 @@             idrisMain opts             addImportDir (sourcedir pkgdesc)             load fs-      idrisInstance  <- run loader idrisInit+      idrisImplementation  <- run loader idrisInit       setCurrentDirectory cd-      case idrisInstance of+      case idrisImplementation of         Left  err -> do           putStrLn $ pshow idrisInit err           exitWith (ExitFailure 1)
src/Idris/Package/Common.hs view
@@ -1,15 +1,14 @@ {-| Module      : Idris.Package.Common Description : Data structures common to all `iPKG` file formats.-Copyright   : License     : BSD3 Maintainer  : The Idris Community. -} module Idris.Package.Common where -import Idris.Core.TT-import Idris.REPL-import Idris.AbsSyntaxTree+import Idris.Core.TT (Name)++import Idris.AbsSyntaxTree (Opt(..))  -- | Description of an Idris package. data PkgDesc = PkgDesc {
src/Idris/Parser.hs view
@@ -179,8 +179,8 @@   | Params   | Mutual   | Namespace-  | Class-  | Instance+  | Interface+  | Implementation   | DSL   | Directive   | Provider@@ -219,14 +219,14 @@                      <|> fail "End of readable input"   where declBody :: Bool -> IdrisParser [PDecl]         declBody b =-                   try (instance_ True syn)+                   try (implementation True syn)                    <|> try (openInterface syn)                    <|> declBody' b                    <|> using_ syn                    <|> params syn                    <|> mutual syn                    <|> namespace syn-                   <|> class_ syn+                   <|> interface_ syn                    <|> do d <- dsl syn; return [d]                    <|> directive syn                    <|> provider syn@@ -316,7 +316,7 @@      -- Below is a lot of tedious boilerplate which updates any top level     -- names in the declaration. It will only change names which are bound in-    -- the declaration (including method names in classes and field names in+    -- the declaration (including method names in interfaces and field names in     -- record declarations, not including pattern variables)     updateB :: [(Name, SynMatch)] -> Name -> Name     updateB ns (NS n mods) = NS (updateB ns n) mods@@ -340,15 +340,15 @@                    (updateRecCon ns cname)                    cdoc                    s-    updateNs ns (PClass docs s fc cs cn fc' ps pdocs pdets ds cname cdocs)-         = PClass docs s fc cs (updateB ns cn) fc' ps pdocs pdets-                  (map (updateNs ns) ds)-                  (updateRecCon ns cname)-                  cdocs-    updateNs ns (PInstance docs pdocs s fc cs pnames acc opts cn fc' ps pextra ity ni ds)-         = PInstance docs pdocs s fc cs pnames acc opts (updateB ns cn) fc'-                     ps pextra ity (fmap (updateB ns) ni)-                            (map (updateNs ns) ds)+    updateNs ns (PInterface docs s fc cs cn fc' ps pdocs pdets ds cname cdocs)+         = PInterface docs s fc cs (updateB ns cn) fc' ps pdocs pdets+                      (map (updateNs ns) ds)+                      (updateRecCon ns cname)+                      cdocs+    updateNs ns (PImplementation docs pdocs s fc cs pnames acc opts cn fc' ps pextra ity ni ds)+         = PImplementation docs pdocs s fc cs pnames acc opts (updateB ns cn) fc'+                           ps pextra ity (fmap (updateB ns) ni)+                           (map (updateNs ns) ds)     updateNs ns (PMutual fc ds) = PMutual fc (map (updateNs ns) ds)     updateNs ns (PProvider docs s fc fc' pw n)         = PProvider docs s fc fc' pw (updateB ns n)@@ -598,7 +598,7 @@ @ -} fnDecl' :: SyntaxInfo -> IdrisParser PDecl-fnDecl' syn = checkFixity $+fnDecl' syn = checkDeclFixity $               do (doc, argDocs, fc, opts', n, nfc, acc) <- try (do                         pushIndent                         (doc, argDocs) <- docstring syn@@ -618,22 +618,6 @@             <|> caf syn             <|> pattern syn             <?> "function declaration"-    where checkFixity :: IdrisParser PDecl -> IdrisParser PDecl-          checkFixity p = do decl <- p-                             case getName decl of-                               Nothing -> return decl-                               Just n -> do fOk <- fixityOK n-                                            unless fOk . fail $-                                              "Missing fixity declaration for " ++ show n-                                            return decl-          getName (PTy _ _ _ _ _ n _ _) = Just n-          getName _ = Nothing-          fixityOK (NS n _) = fixityOK n-          fixityOK (UN n)  | all (flip elem opChars) (str n) =-                               do fixities <- fmap idris_infixes get-                                  return . elem (str n) . map (\ (Fix _ op) -> op) $ fixities-                           | otherwise                 = return True-          fixityOK _        = return True  {-| Parses a series of function and accessbility options @@ -701,6 +685,8 @@                     return NoImplicit         <|> do try (lchar '%' *> reserved "inline");                     return Inlinable+        <|> do try (lchar '%' *> reserved "static");+                    return StaticFn         <|> do try (lchar '%' *> reserved "assert_total");                fc <- getFC                parserWarning fc Nothing (Msg "%assert_total is deprecated. Use the 'assert_total' function instead.")@@ -846,53 +832,52 @@        return [PNamespace n nfc (concat ds)]      <?> "namespace declaration" -{-| Parses a methods block (for instances)+{-| Parses a methods block (for implementations)  @-  InstanceBlock ::= 'where' OpenBlock FnDecl* CloseBlock+  ImplementationBlock ::= 'where' OpenBlock FnDecl* CloseBlock @ -}-instanceBlock :: SyntaxInfo -> IdrisParser [PDecl]-instanceBlock syn = do reservedHL "where"-                       openBlock-                       ds <- many (fnDecl syn)-                       closeBlock-                       return (concat ds)-                    <?> "implementation block"+implementationBlock :: SyntaxInfo -> IdrisParser [PDecl]+implementationBlock syn = do reservedHL "where"+                             openBlock+                             ds <- many (fnDecl syn)+                             closeBlock+                             return (concat ds)+                          <?> "implementation block" -{-| Parses a methods and instances block (for type classes)+{-| Parses a methods and implementations block (for interfaces)  @-MethodOrInstance ::=+MethodOrImplementation ::=    FnDecl-   | Instance+   | Implementation    ; @  @-ClassBlock ::=-  'where' OpenBlock Constructor? MethodOrInstance* CloseBlock+InterfaceBlock ::=+  'where' OpenBlock Constructor? MethodOrImplementation* CloseBlock   ; @ -}-classBlock :: SyntaxInfo -> IdrisParser (Maybe (Name, FC), Docstring (Either Err PTerm), [PDecl])-classBlock syn = do reservedHL "where"-                    openBlock-                    (cn, cd) <- option (Nothing, emptyDocstring) $-                                try (do (doc, _) <- option noDocs docComment-                                        n <- constructor-                                        return (Just n, doc))-                    ist <- get-                    let cd' = annotate syn ist cd--                    ds <- many (notEndBlock >> try (instance_ True syn)-                                               <|> do x <- data_ syn-                                                      return [x]-                                               <|> fnDecl syn)-                    closeBlock-                    return (cn, cd', concat ds)-                 <?> "class block"+interfaceBlock :: SyntaxInfo -> IdrisParser (Maybe (Name, FC), Docstring (Either Err PTerm), [PDecl])+interfaceBlock syn = do reservedHL "where"+                        openBlock+                        (cn, cd) <- option (Nothing, emptyDocstring) $+                                    try (do (doc, _) <- option noDocs docComment+                                            n <- constructor+                                            return (Just n, doc))+                        ist <- get+                        let cd' = annotate syn ist cd +                        ds <- many (notEndBlock >> try (implementation True syn)+                                                   <|> do x <- data_ syn+                                                          return [x]+                                                   <|> fnDecl syn)+                        closeBlock+                        return (cn, cd', concat ds)+                     <?> "interface block"   where     constructor :: IdrisParser (Name, FC)     constructor = reservedHL "constructor" *> fnName@@ -900,44 +885,44 @@     annotate :: SyntaxInfo -> IState -> Docstring () -> Docstring (Either Err PTerm)     annotate syn ist = annotCode $ tryFullExpr syn ist -{-| Parses a type class declaration+{-| Parses an interface declaration  @-ClassArgument ::=+InterfaceArgument ::=    Name    | '(' Name ':' Expr ')'    ; @  @-Class ::=-  DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* ClassBlock?+Interface ::=+  DocComment_t? Accessibility? 'interface' ConstraintList? Name InterfaceArgument* InterfaceBlock?   ; @ -}-class_ :: SyntaxInfo -> IdrisParser [PDecl]-class_ syn = do (doc, argDocs, acc)-                  <- try (do (doc, argDocs) <- docstring syn-                             acc <- accessibility-                             classKeyword-                             return (doc, argDocs, acc))-                fc <- getFC-                cons <- constraintList syn-                let cons' = [(c, ty) | (c, _, ty) <- cons]-                (n_in, nfc) <- fnName-                let n = expandNS syn n_in-                cs <- many carg-                fds <- option [(cn, NoFC) | (cn, _, _) <- cs] fundeps-                (cn, cd, ds) <- option (Nothing, fst noDocs, []) (classBlock syn)-                accData acc n (concatMap declared ds)-                return [PClass doc syn fc cons' n nfc cs argDocs fds ds cn cd]-             <?> "type-class declaration"+interface_ :: SyntaxInfo -> IdrisParser [PDecl]+interface_ syn = do (doc, argDocs, acc)+                      <- try (do (doc, argDocs) <- docstring syn+                                 acc <- accessibility+                                 interfaceKeyword+                                 return (doc, argDocs, acc))+                    fc <- getFC+                    cons <- constraintList syn+                    let cons' = [(c, ty) | (c, _, ty) <- cons]+                    (n_in, nfc) <- fnName+                    let n = expandNS syn n_in+                    cs <- many carg+                    fds <- option [(cn, NoFC) | (cn, _, _) <- cs] fundeps+                    (cn, cd, ds) <- option (Nothing, fst noDocs, []) (interfaceBlock syn)+                    accData acc n (concatMap declared ds)+                    return [PInterface doc syn fc cons' n nfc cs argDocs fds ds cn cd]+                 <?> "interface declaration"   where     fundeps :: IdrisParser [(Name, FC)]     fundeps = do lchar '|'; sepBy name (lchar ',') -    classKeyword :: IdrisParser ()-    classKeyword = reservedHL "interface"+    interfaceKeyword :: IdrisParser ()+    interfaceKeyword = reservedHL "interface"                <|> do reservedHL "class"                       fc <- getFC                       parserWarning fc Nothing (Msg "The 'class' keyword is deprecated. Use 'interface' instead.")@@ -949,55 +934,55 @@               fc <- getFC               return (i, ifc, PType fc) -{-| Parses a type class instance declaration+{-| Parses an interface implementation declaration  @-  Instance ::=-    DocComment_t? 'instance' InstanceName? ConstraintList? Name SimpleExpr* InstanceBlock?+  Implementation ::=+    DocComment_t? 'implementation' ImplementationName? ConstraintList? Name SimpleExpr* ImplementationBlock?     ; @  @-InstanceName ::= '[' Name ']';+ImplementationName ::= '[' Name ']'; @ -}-instance_ :: Bool -> SyntaxInfo -> IdrisParser [PDecl]-instance_ kwopt syn-              = do ist <- get-                   (doc, argDocs) <- docstring syn-                   (opts, acc) <- fnOpts-                   if kwopt then optional instanceKeyword-                            else do instanceKeyword-                                    return (Just ())+implementation :: Bool -> SyntaxInfo -> IdrisParser [PDecl]+implementation kwopt syn+                   = do ist <- get+                        (doc, argDocs) <- docstring syn+                        (opts, acc) <- fnOpts+                        if kwopt then optional implementationKeyword+                                 else do implementationKeyword+                                         return (Just ()) -                   fc <- getFC-                   en <- optional instanceName-                   cs <- constraintList syn-                   let cs' = [(c, ty) | (c, _, ty) <- cs]-                   (cn, cnfc) <- fnName-                   args <- many (simpleExpr syn)-                   let sc = PApp fc (PRef cnfc [cnfc] cn) (map pexp args)-                   let t = bindList (PPi constraint) cs sc-                   pnames <- instanceUsing-                   ds <- instanceBlock syn-                   return [PInstance doc argDocs syn fc cs' pnames acc opts cn cnfc args [] t en ds]-                 <?> "implementation declaration"-  where instanceName :: IdrisParser Name-        instanceName = do lchar '['; n_in <- fst <$> fnName; lchar ']'-                          let n = expandNS syn n_in-                          return n-                       <?> "implementation name"-        instanceKeyword :: IdrisParser ()-        instanceKeyword = reservedHL "implementation"-                      <|> do reservedHL "instance"-                             fc <- getFC-                             parserWarning fc Nothing (Msg "The 'instance' keyword is deprecated. Use 'implementation' (or omit it) instead.")+                        fc <- getFC+                        en <- optional implementationName+                        cs <- constraintList syn+                        let cs' = [(c, ty) | (c, _, ty) <- cs]+                        (cn, cnfc) <- fnName+                        args <- many (simpleExpr syn)+                        let sc = PApp fc (PRef cnfc [cnfc] cn) (map pexp args)+                        let t = bindList (PPi constraint) cs sc+                        pnames <- implementationUsing+                        ds <- implementationBlock syn+                        return [PImplementation doc argDocs syn fc cs' pnames acc opts cn cnfc args [] t en ds]+                      <?> "implementation declaration"+  where implementationName :: IdrisParser Name+        implementationName = do lchar '['; n_in <- fst <$> fnName; lchar ']'+                                let n = expandNS syn n_in+                                return n+                             <?> "implementation name"+        implementationKeyword :: IdrisParser ()+        implementationKeyword = reservedHL "implementation"+                         <|> do reservedHL "instance"+                                fc <- getFC+                                parserWarning fc Nothing (Msg "The 'instance' keyword is deprecated. Use 'implementation' (or omit it) instead.") -        instanceUsing :: IdrisParser [Name]-        instanceUsing = do reservedHL "using"-                           ns <- sepBy1 fnName (lchar ',')-                           return (map fst ns)-                        <|> return []+        implementationUsing :: IdrisParser [Name]+        implementationUsing = do reservedHL "using"+                                 ns <- sepBy1 fnName (lchar ',')+                                 return (map fst ns)+                              <|> return []  -- | Parse a docstring docstring :: SyntaxInfo@@ -1880,9 +1865,9 @@     toMutual x = let r = PMutual (fileFC "single mutual") [x] in                  case x of                    PClauses{} -> r-                   PClass{} -> r+                   PInterface{} -> r                    PData{} -> r-                   PInstance{} -> r+                   PImplementation{} -> r                    _ -> x      addModDoc :: SyntaxInfo -> [String] -> Docstring () -> Idris ()
src/Idris/Parser/Data.hs view
@@ -198,7 +198,8 @@   ; -} data_ :: SyntaxInfo -> IdrisParser PDecl-data_ syn = do (doc, argDocs, acc, dataOpts) <- try (do+data_ syn = checkDeclFixity $+            do (doc, argDocs, acc, dataOpts) <- try (do                     (doc, argDocs) <- option noDocs docComment                     pushIndent                     acc <- accessibility@@ -277,6 +278,7 @@          let doc' = annotCode (tryFullExpr syn ist) doc              argDocs' = [ (n, annotCode (tryFullExpr syn ist) d)                         | (n, d) <- argDocs ]+         checkNameFixity cn          return (doc', argDocs', cn, nfc, ty, fc, fs)       <?> "constructor" @@ -293,6 +295,7 @@           fc <- getFC           args <- many (do notEndApp                            simpleExpr syn)+          checkNameFixity cn           return (doc', [], cn, nfc, args, fc, [])        <?> "constructor" 
src/Idris/Parser/Expr.hs view
@@ -385,7 +385,7 @@ SimpleExpr ::=     {- External (User-defined) Simple Expression -}   | '?' Name-  | % 'instance'+  | % 'implementation'   | 'Refl' ('{' Expr '}')?   | ProofExpr   | TacticsExpr@@ -409,15 +409,18 @@             try (simpleExternalExpr syn)         <|> do (x, FC f (l, c) end) <- try (lchar '?' *> name)                return (PMetavar (FC f (l, c-1) end) x)-        <|> do lchar '%'; fc <- getFC; reserved "instance"; return (PResolveTC fc)+        <|> do lchar '%'; fc <- getFC; reserved "implementation"; return (PResolveTC fc)+        <|> do lchar '%'; fc <- getFC; reserved "instance"+               parserWarning fc Nothing $ Msg "The use of %instance is deprecated, use %implementation instead."+               return (PResolveTC fc)         <|> do reserved "elim_for"; fc <- getFC; t <- fst <$> fnName; return (PRef fc [] (SN $ ElimN t))         <|> proofExpr syn         <|> tacticsExpr syn-        <|> try (do reserved "Type*"; return $ PUniverse AllTypes)-        <|> do reserved "AnyType"; return $ PUniverse AllTypes+        <|> try (do fc <- reservedFC "Type*"; return $ PUniverse fc AllTypes)+        <|> do fc <- reservedFC "AnyType"; return $ PUniverse fc AllTypes         <|> PType <$> reservedFC "Type"-        <|> do reserved "UniqueType"; return $ PUniverse UniqueType-        <|> do reserved "NullType"; return $ PUniverse NullType+        <|> do fc <- reservedFC "UniqueType"; return $ PUniverse fc UniqueType+        <|> do fc <- reservedFC "NullType"; return $ PUniverse fc NullType         <|> do (c, cfc) <- constant                fc <- getFC                return (modifyConst syn fc (PConstant cfc c))@@ -740,7 +743,7 @@                      return (pimp n v True)                   <?> "implicit function argument" -{-| Parses a constraint argument (for selecting a named type class instance)+{-| Parses a constraint argument (for selecting a named interface implementation)  >    ConstraintArg ::= >      '@{' Expr '}'@@ -1287,7 +1290,7 @@                                qs <- sepBy1 (do_ syn) (lchar ',')                                lchar ']'                                return (PDoBlock (map addGuard qs ++-                                          [DoExp fc (PApp fc (PRef fc [] (sUN "return"))+                                          [DoExp fc (PApp fc (PRef fc [] (sUN "pure"))                                                        [pexp x])]))) <|>                             (do xs <- many (do (FC fn (sl, sc) _) <- getFC                                                lchar ',' <?> "list element"@@ -1467,7 +1470,7 @@  @ Static ::=-  '[' static ']'+  '%static' ; @ -}@@ -1582,7 +1585,7 @@   , (["search"], Nothing, const $       do depth <- option 10 $ fst <$> natural          return (ProofSearch True True (fromInteger depth) Nothing [] []))-  , noArgs ["instance"] TCInstance+  , noArgs ["implementation"] TCImplementation   , noArgs ["solve"] Solve   , noArgs ["attack"] Attack   , noArgs ["state", ":state"] ProofState
src/Idris/Parser/Helpers.hs view
@@ -676,7 +676,7 @@                 put (i { hide_list = addDef n a (hide_list i) })  {- | Add accessbility option for data declarations- (works for classes too - 'abstract' means the data/class is visible but members not) -}+ (works for interfaces too - 'abstract' means the data/interface is visible but members not) -} accData :: Accessibility -> Name -> [Name] -> IdrisParser () accData Frozen n ns = do addAcc n Public -- so that it can be used in public definitions                          mapM_ (\n -> addAcc n Private) ns -- so that they are invisible@@ -713,9 +713,9 @@ collect (POpenInterfaces f ns ps : ds) = POpenInterfaces f ns (collect ps) : collect ds collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds collect (PNamespace ns fc ps : ds) = PNamespace ns fc (collect ps) : collect ds-collect (PClass doc f s cs n nfc ps pdocs fds ds cn cd : ds')-    = PClass doc f s cs n nfc ps pdocs fds (collect ds) cn cd : collect ds'-collect (PInstance doc argDocs f s cs pnames acc opts n nfc ps pextra t en ds : ds')-    = PInstance doc argDocs f s cs pnames acc opts n nfc ps pextra t en (collect ds) : collect ds'+collect (PInterface doc f s cs n nfc ps pdocs fds ds cn cd : ds')+    = PInterface doc f s cs n nfc ps pdocs fds (collect ds) cn cd : collect ds'+collect (PImplementation doc argDocs f s cs pnames acc opts n nfc ps pextra t en ds : ds')+    = PImplementation doc argDocs f s cs pnames acc opts n nfc ps pextra t en (collect ds) : collect ds' collect (d : ds) = d : collect ds collect [] = []
src/Idris/Parser/Ops.hs view
@@ -161,6 +161,29 @@                    extractName :: FixDecl -> String                    extractName (Fix _ n) = n +-- | Check that a declaration of an operator also has fixity declared+checkDeclFixity :: IdrisParser PDecl -> IdrisParser PDecl+checkDeclFixity p = do decl <- p+                       case getDeclName decl of+                         Nothing -> return decl+                         Just n -> do checkNameFixity n+                                      return decl+  where getDeclName (PTy _ _ _ _ _ n _ _ )                = Just n+        getDeclName (PData _ _ _ _ _ (PDatadecl n _ _ _)) = Just n+        getDeclName _ = Nothing++-- | Checks that an operator name also has a fixity declaration+checkNameFixity :: Name -> IdrisParser ()+checkNameFixity n = do fOk <- fixityOk n+                       unless fOk . fail $+                         "Missing fixity declaration for " ++ show n+      where fixityOk (NS n' _) = fixityOk n'+            fixityOk (UN n') | all (flip elem opChars) (str n') =+                                 do fixities <- fmap idris_infixes get+                                    return . elem (str n') . map (\ (Fix _ op) -> op) $ fixities+                             | otherwise = return True+            fixityOk _ = return True+ {- | Parses a fixity declaration type (i.e. infix or prefix, associtavity) @     FixityType ::=
src/Idris/PartialEval.hs view
@@ -141,8 +141,8 @@     mkty ((ExplicitD, v) : xs) (Bind n (Pi _ t k) sc)        = PPi expl n NoFC (delab ist (generaliseIn t)) (mkty xs sc)     mkty ((ImplicitD, v) : xs) (Bind n (Pi _ t k) sc)-         | concreteClass ist t = mkty xs sc-         | classConstraint ist t+         | concreteInterface ist t = mkty xs sc+         | interfaceConstraint ist t              = PPi constraint n NoFC (delab ist (generaliseIn t)) (mkty xs sc)          | otherwise = PPi impl n NoFC (delab ist (generaliseIn t)) (mkty xs sc) @@ -160,19 +160,19 @@     gen (App s f a) = App s <$> gen f <*> gen a     gen tm = return tm --- | Checks if a given argument is a type class constraint argument-classConstraint :: Idris.AbsSyntax.IState -> TT Name -> Bool-classConstraint ist v-    | (P _ c _, args) <- unApply v = case lookupCtxt c (idris_classes ist) of+-- | Checks if a given argument is an interface constraint argument+interfaceConstraint :: Idris.AbsSyntax.IState -> TT Name -> Bool+interfaceConstraint ist v+    | (P _ c _, args) <- unApply v = case lookupCtxt c (idris_interfaces ist) of                                           [_] -> True                                           _ -> False     | otherwise = False --- | Checks if the given arguments of a type class constraint are all either constants+-- | Checks if the given arguments of an interface constraint are all either constants -- or references (i.e. that it doesn't contain any complex terms).-concreteClass :: IState -> TT Name -> Bool-concreteClass ist v-    | not (classConstraint ist v) = False+concreteInterface :: IState -> TT Name -> Bool+concreteInterface ist v+    | not (interfaceConstraint ist v) = False     | (P _ c _, args) <- unApply v = all concrete args     | otherwise = False   where concrete (Constant _) = True
src/Idris/ProofSearch.hs view
@@ -101,7 +101,7 @@          tcArg env ty            | (P _ n _, args) <- unApply (getRetTy (normalise (tt_ctxt ist) env ty))-                 = case lookupCtxtExact n (idris_classes ist) of+                 = case lookupCtxtExact n (idris_interfaces ist) of                         Just _ -> True                         _ -> False            | otherwise = False@@ -352,7 +352,7 @@  -- | Resolve interfaces. This will only pick up 'normal' -- implementations, never named implementations (which is enforced by--- 'findInstances').+-- 'findImplementations'). resolveTC :: Bool                -- ^ using default Int           -> Bool                -- ^ allow open implementations           -> Int                 -- ^ depth@@ -403,22 +403,22 @@                               P _ n _ -> zip (repeat n) okholePos                               _ -> [] -           traceWhen ulog ("Resolving class " ++ show g ++ "\nin" ++ show env ++ "\n" ++ show okholes) $+           traceWhen ulog ("Resolving interface " ++ show g ++ "\nin" ++ show env ++ "\n" ++ show okholes) $             try' (trivialTCs okholes elab ist)                 (do addDefault t tc ttypes                     let stk = map fst (filter snd $ elab_stack ist)-                    let insts = idris_openimpls ist ++ findInstances ist t-                    blunderbuss t depth stk (stk ++ insts)) True+                    let impls = idris_openimpls ist ++ findImplementations ist t+                    blunderbuss t depth stk (stk ++ impls)) True      -- returns Just hs if okay, where hs are holes which are okay in the     -- goal, or Nothing if not okay to proceed-    tcArgsOK ty hs | (P _ nc _, as) <- unApply (getRetTy ty), nc == numclass && defaultOn+    tcArgsOK ty hs | (P _ nc _, as) <- unApply (getRetTy ty), nc == numinterface && defaultOn        = Just []     tcArgsOK ty hs -- if any determining arguments are metavariables, postpone        = let (f, as) = unApply (getRetTy ty) in              case f of-                  P _ cn _ -> case lookupCtxtExact cn (idris_classes ist) of-                                   Just ci -> tcDetArgsOK 0 (class_determiners ci) hs as+                  P _ cn _ -> case lookupCtxtExact cn (idris_interfaces ist) of+                                   Just ci -> tcDetArgsOK 0 (interface_determiners ci) hs as                                    Nothing -> if any (isMeta hs) as                                                  then Nothing                                                  else Just []@@ -451,9 +451,9 @@        | Constant _ <- c = not (n `elem` hs)     notHole _ _ = True -    numclass = sNS (sUN "Num") ["Interfaces","Prelude"]+    numinterface = sNS (sUN "Num") ["Interfaces","Prelude"] -    addDefault t num@(P _ nc _) [P Bound a _] | nc == numclass && defaultOn+    addDefault t num@(P _ nc _) [P Bound a _] | nc == numinterface && defaultOn         = do focus a              fill (RConstant (AType (ATInt ITBig))) -- default Integer              solve@@ -489,7 +489,7 @@            = do lams <- introImps                 t <- goal                 let (tc, ttypes) = trace (show t) $ unApply (getRetTy t)---                 if (all boundVar ttypes) then resolveTC (depth - 1) fn insts ist+--                 if (all boundVar ttypes) then resolveTC (depth - 1) fn impls ist --                   else do                    -- if there's a hole in the goal, don't even try                 let imps = case lookupCtxtName n (idris_implicits ist) of@@ -522,10 +522,10 @@  -- | Find the names of implementations that have been designeated for -- searching (i.e. non-named implementations or implementations from Elab scripts)-findInstances :: IState -> Term -> [Name]-findInstances ist t+findImplementations :: IState -> Term -> [Name]+findImplementations ist t     | (P _ n _, _) <- unApply (getRetTy t)-        = case lookupCtxt n (idris_classes ist) of+        = case lookupCtxt n (idris_interfaces ist) of             [CI _ _ _ _ _ ins _] ->               [n | (n, True) <- ins, accessible n]             _ -> []
src/Idris/Providers.hs view
@@ -24,7 +24,7 @@   = PApp fc (PRef fc [] $ sNS (sUN "Provider" ) ["Providers", "Prelude"]) [PExp 0 [] (sMN 0 "pvarg") tm]  ioret :: Name-ioret = sUN "prim_io_return"+ioret = sUN "prim_io_pure"  ermod :: Name ermod = sNS (sUN "Error") ["Providers", "Prelude"]@@ -48,5 +48,5 @@                   , pioret == ioret && nm == prmod                       = return . Provide $ res                   | otherwise = ifail $ "Internal type provider error: result was not " ++-                                        "IO (Provider a), or perhaps missing normalisation." +++                                        "IO (Provider a), or perhaps missing normalisation.\n" ++                                         "Term: " ++ take 1000 (show tm)
src/Idris/REPL.hs view
@@ -1,59 +1,54 @@ {-| Module      : Idris.REPL Description : Entry Point for the Idris REPL and CLI.-Copyright   : License     : BSD3 Maintainer  : The Idris Community. -} {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,              PatternGuards, CPP #-}--module Idris.REPL(-    getClient, getPkg, getPkgCheck, getPkgClean, getPkgMkDoc-  , getPkgREPL, getPkgTest, getPort, getIBCSubDir-  , idris, idrisMain, loadInputs-  , opt, runClient, runMain, ver+module Idris.REPL+  ( idemodeStart+  , startServer+  , runClient+  , process+  , replSettings+  , repl+  , proofs   ) where  import Idris.AbsSyntax import Idris.ASTUtils import Idris.Apropos (apropos, aproposModules) import Idris.REPL.Parser-import Idris.Erasure import Idris.Error import Idris.IBC import Idris.ErrReverse import Idris.Delaborate-import Idris.Docstrings (Docstring, overview, renderDocstring, renderDocTerm)+import Idris.Docstrings (overview, renderDocstring, renderDocTerm) import Idris.Help import Idris.IdrisDoc import Idris.Prover import Idris.Parser hiding (indent)-import Idris.Primitives import Idris.Coverage import Idris.Docs hiding (Doc) import Idris.Completion import qualified Idris.IdeMode as IdeMode-import Idris.Chaser-import Idris.Imports import Idris.Colours hiding (colourise) import Idris.Inliner-import Idris.CaseSplit-import Idris.DeepSeq import Idris.Output import Idris.Interactive import Idris.WhoCalls import Idris.TypeSearch (searchByType)-import Idris.IBC (loadPkgIndex, writePkgIndex)  import Idris.REPL.Browse (namesInNS, namespacesInNS)+import Idris.REPL.Commands  import Idris.ElabDecls-import Idris.Elab.Type import Idris.Elab.Clause-import Idris.Elab.Data import Idris.Elab.Value import Idris.Elab.Term+import Idris.ModeCommon+import Idris.Info  import Version_idris (gitHash) import Util.System@@ -69,21 +64,25 @@ import Idris.Core.Constraints  import IRTS.Compiler-import IRTS.CodegenCommon-import IRTS.Exports-import IRTS.System  import Control.Category import qualified Control.Exception as X import Prelude hiding ((<$>), (.), id) import Data.List.Split (splitOn)-import Data.List (groupBy) import qualified Data.Text as T  import Text.Trifecta.Result(Result(..), ErrInfo(..))  import System.Console.Haskeline as H import System.FilePath+  ( (</>)+  , (<.>)+  , splitExtension+  , addExtension+  , dropExtension+  , takeExtension+  , takeDirectory+  ) import System.Exit import System.Environment import System.Process@@ -101,7 +100,6 @@ import Data.Char import qualified Data.Set as S import Data.Version-import Data.Word (Word) import Data.Either (partitionEithers) import Control.DeepSeq @@ -109,9 +107,7 @@ import System.FSNotify (withManager, watchDir) import System.FSNotify.Devel (allEvents, doAllEvents) -import Numeric ( readHex ) -import Debug.Trace  -- | Run the REPL repl :: IState -- ^ The initial state@@ -166,7 +162,7 @@                               else show n  -- | Run the REPL server-startServer :: PortID -> IState -> [FilePath] -> Idris ()+startServer :: PortNumber -> IState -> [FilePath] -> Idris () startServer port orig fn_in = do tid <- runIO $ forkIO (serverLoop port)                                  return ()   where serverLoop port = withSocketsDo $@@ -225,9 +221,10 @@            IdeMode n _ -> ist {idris_outputmode = IdeMode n h}  -- | Run a command on the server on localhost-runClient :: PortID -> String -> IO ()+runClient :: Maybe PortNumber -> String -> IO () runClient port str = withSocketsDo $ do-              res <- X.try (connectTo "localhost" port)+              let port' = fromMaybe defaultPort port+              res <- X.try (connectTo "localhost" $ PortNumber port')               case res of                 Right h -> do                   hSetEncoding h utf8@@ -567,7 +564,7 @@          msg = (IdeMode.SymbolAtom "ok", out, spans)      runIO . hPutStrLn h $ IdeMode.convSExp "return" msg id runIdeModeCommand h id orig fn modes IdeMode.GetIdrisVersion =-  let idrisVersion = (versionBranch version,+  let idrisVersion = (versionBranch getIdrisVersionNoGit,                       if not (null gitHash)                         then [gitHash]                         else [])@@ -785,10 +782,10 @@          env <- runIO getEnvironment          let editor = getEditor env          let line = case errSpan i of-                        Just l -> ['+' : show (fst (fc_start l))]-                        Nothing -> []-         let args = line ++ [fixName f]-         runIO $ rawSystem editor args+                        Just l -> '+' : show (fst (fc_start l))+                        Nothing -> ""+         let cmdLine = intercalate " " [editor, line, fixName f]+         runIO $ system cmdLine          clearErr   -- The $!! here prevents a space leak on reloading.   -- This isn't a solution - but it's a temporary stopgap.@@ -803,8 +800,11 @@    where getEditor env | Just ed <- lookup "EDITOR" env = ed                        | Just ed <- lookup "VISUAL" env = ed                        | otherwise = "vi"-         fixName file | map toLower (takeExtension file) `elem` [".lidr", ".idr"] = file-                      | otherwise = addExtension file "idr"+         fixName file | map toLower (takeExtension file) `elem` [".lidr", ".idr"] = quote file+                      | otherwise = quote $ addExtension file "idr"+            where+                quoteChar = if isWindows then '"' else '\''+                quote s = [quoteChar] ++ s ++ [quoteChar]   @@ -864,7 +864,7 @@   getName (PTy docs argdocs syn fc opts name _ ty) = Just name   getName (PClauses fc opts name (clause:clauses)) = Just (getClauseName clause)   getName (PData doc argdocs syn fc opts dataDecl) = Just (d_name dataDecl)-  getName (PClass doc syn fc constraints name nfc parms parmdocs fds decls _ _) = Just name+  getName (PInterface doc syn fc constraints name nfc parms parmdocs fds decls _ _) = Just name   getName _ = Nothing   -- getClauseName is partial and I am not sure it's used safely! -- trillioneyes   getClauseName (PClause fc name whole with rhs whereBlock) = name@@ -912,8 +912,8 @@   fixClauses :: PDecl' t -> PDecl' t   fixClauses (PClauses fc opts _ css@(clause:cs)) =     PClauses fc opts (getClauseName clause) css-  fixClauses (PInstance doc argDocs syn fc constraints pnames acc opts cls nfc parms pextra ty instName decls) =-    PInstance doc argDocs syn fc constraints pnames acc opts cls nfc parms pextra ty instName (map fixClauses decls)+  fixClauses (PImplementation doc argDocs syn fc constraints pnames acc opts cls nfc parms pextra ty implName decls) =+    PImplementation doc argDocs syn fc constraints pnames acc opts cls nfc parms pextra ty implName (map fixClauses decls)   fixClauses decl = decl    info = recinfo (fileFC "toplevel")@@ -937,9 +937,9 @@          else do tclift $ tfail $ Msg ("Can't undefine " ++ show n ++ " because it wasn't defined at the repl")                  undefine' names already     undefOne n = do fputState (ctxt_lookup n . known_terms) Nothing-                    -- for now just assume it's a class. Eventually we'll want some kind of+                    -- for now just assume it's an interface. Eventually we'll want some kind of                     -- smart detection of exactly what kind of name we're undefining.-                    fputState (ctxt_lookup n . known_classes) Nothing+                    fputState (ctxt_lookup n . known_interfaces) Nothing                     fmodifyState repl_definitions (delete n)     undefClosure n =       do replDefs <- idris_repl_defs `fmap` get@@ -1017,8 +1017,16 @@                                    (pprintDelab ist ty')  process fn (Core t)-   = do (tm, ty) <- elabREPL (recinfo (fileFC "toplevel")) ERHS t-        iPrintTermWithType (pprintTT [] tm) (pprintTT [] ty)+   = case t of+       PRef _ _ n ->+         do ist <- getIState+            case lookupDef n (tt_ctxt ist) of+              [CaseOp _ _ _ _ _ _] -> pprintDef True n >>= iRenderResult . vsep+              _ -> coreTerm t+       t -> coreTerm t+   where coreTerm t =+           do (tm, ty) <- elabREPL (recinfo (fileFC "toplevel")) ERHS t+              iPrintTermWithType (pprintTT [] tm) (pprintTT [] ty)  process fn (DocStr (Left n) w)   | UN ty <- n, ty == T.pack "Type" = getIState >>= iRenderResult . pprintTypeDoc@@ -1411,7 +1419,7 @@          case result of Right _   -> iputStrLn "IdrisDoc generated"                         Left  err -> iPrintError err process fn (PrintDef n) =-  do result <- pprintDef n+  do result <- pprintDef False n      case result of        [] -> iPrintError "Not found"        outs -> iRenderResult . vsep $ outs@@ -1438,7 +1446,7 @@ --                    showTrans i ts  process fn (PPrint fmt width (PRef _ _ n))-   = do outs <- pprintDef n+   = do outs <- pprintDef False n         iPrintResult =<< renderExternal fmt width (vsep outs)  @@ -1472,7 +1480,7 @@        showN n = annotate (AnnName n Nothing Nothing Nothing) . text $                  showName (Just ist) [] ppo False n -displayHelp = let vstr = showVersion version in+displayHelp = let vstr = showVersion getIdrisVersionNoGit in               "\nIdris version " ++ vstr ++ "\n" ++               "--------------" ++ map (\x -> '-') vstr ++ "\n\n" ++               concatMap cmdInfo helphead ++@@ -1482,17 +1490,26 @@             l ++ take (c1 - length l) (repeat ' ') ++             m ++ take (c2 - length m) (repeat ' ') ++ r ++ "\n" -pprintDef :: Name -> Idris [Doc OutputAnnotation]-pprintDef n =+pprintDef :: Bool -> Name -> Idris [Doc OutputAnnotation]+pprintDef asCore n =   do ist <- getIState      ctxt <- getContext      let ambiguous = length (lookupNames n ctxt) > 1          patdefs = idris_patdefs ist          tyinfo = idris_datatypes ist-     return $ map (ppDef ambiguous ist) (lookupCtxtName n patdefs) ++-              map (ppTy ambiguous ist) (lookupCtxtName n tyinfo) ++-              map (ppCon ambiguous ist) (filter (flip isDConName ctxt) (lookupNames n ctxt))-  where ppDef :: Bool -> IState -> (Name, ([([(Name, Term)], Term, Term)], [PTerm])) -> Doc OutputAnnotation+     if asCore+       then return $ map (ppCoreDef ist) (lookupCtxtName n patdefs)+       else return $ map (ppDef ambiguous ist) (lookupCtxtName n patdefs) +++                     map (ppTy ambiguous ist) (lookupCtxtName n tyinfo) +++                     map (ppCon ambiguous ist) (filter (flip isDConName ctxt) (lookupNames n ctxt))+  where ppCoreDef :: IState -> (Name, ([([(Name, Term)], Term, Term)], [PTerm])) -> Doc OutputAnnotation+        ppCoreDef ist (n, (clauses, missing)) =+          case lookupTy n (tt_ctxt ist) of+            [] -> error "Attempted pprintDef of TT of thing that doesn't exist"+            (ty:_) -> prettyName True True [] n <+> colon <+>+                      align (annotate (AnnTerm [] ty) (pprintTT [] ty)) <$>+                      vsep (map (\(vars, lhs, rhs) ->  pprintTTClause vars lhs rhs) clauses)+        ppDef :: Bool -> IState -> (Name, ([([(Name, Term)], Term, Term)], [PTerm])) -> Doc OutputAnnotation         ppDef amb ist (n, (clauses, missing)) =           prettyName True amb [] n <+> colon <+>           align (pprintDelabTy ist n) <$>@@ -1503,7 +1520,7 @@                   let ppTm t = annotate (AnnTerm (zip vars (repeat False)) t) .                                pprintPTerm (ppOptionIst ist)                                      (zip vars (repeat False))-                                     [] [] .+                                     [] (idris_infixes ist) .                                delab ist $                                t                   in group $ ppTm lhs <+> text "=" <$> (group . align . hang 2 $ ppTm rhs)@@ -1532,510 +1549,3 @@                        historyFile = hFile                      } --- | Invoke as if from command line. It is an error if there are unresolved totality problems.-idris :: [Opt] -> IO (Maybe IState)-idris opts = do res <- runExceptT $ execStateT totalMain idrisInit-                case res of-                  Left err -> do putStrLn $ pshow idrisInit err-                                 return Nothing-                  Right ist -> return (Just ist)-    where totalMain = do idrisMain opts-                         ist <- getIState-                         case idris_totcheckfail ist of-                           ((fc, msg):_) -> ierror . At fc . Msg $ "Could not build: "++  msg-                           [] -> return ()---loadInputs :: [FilePath] -> Maybe Int -> Idris [FilePath]-loadInputs inputs toline -- furthest line to read in input source files-  = idrisCatch-       (do ist <- getIState-           -- if we're in --check and not outputting anything, don't bother-           -- loading, as it gets really slow if there's lots of modules in-           -- a package (instead, reload all at the end to check for-           -- consistency only)-           opts <- getCmdLine--           let loadCode = case opt getOutput opts of-                               [] -> not (NoREPL `elem` opts)-                               _ -> True--           -- For each ifile list, check it and build ibcs in the same clean IState-           -- so that they don't interfere with each other when checking--           importlists <- getImports [] inputs--           logParser 1 (show (map (\(i,m) -> (i, map import_path m)) importlists))--           let ninputs = zip [1..] inputs-           ifiles <- mapWhileOK (\(num, input) ->-                do putIState ist-                   modTree <- buildTree-                                   (map snd (take (num-1) ninputs))-                                   importlists-                                   input-                   let ifiles = getModuleFiles modTree-                   logParser 1 ("MODULE TREE : " ++ show modTree)-                   logParser 1 ("RELOAD: " ++ show ifiles)-                   when (not (all ibc ifiles) || loadCode) $-                        tryLoad False IBC_Building (filter (not . ibc) ifiles)-                   -- return the files that need rechecking-                   return (input, ifiles))-                      ninputs-           inew <- getIState-           let tidata = idris_tyinfodata inew-           -- If it worked, load the whole thing from all the ibcs together-           case errSpan inew of-              Nothing ->-                do putIState $!! ist { idris_tyinfodata = tidata }-                   ibcfiles <- mapM findNewIBC (nub (concatMap snd ifiles))---                    logLvl 0 $ "Loading from " ++ show ibcfiles-                   tryLoad True (IBC_REPL True) (mapMaybe id ibcfiles)-              _ -> return ()-           exports <- findExports--           case opt getOutput opts of-               [] -> performUsageAnalysis (getExpNames exports) -- interactive-               _  -> return []  -- batch, will be checked by the compiler--           return (map fst ifiles))-        (\e -> do i <- getIState-                  case e of-                    At f e' -> do setErrSpan f-                                  iWarn f $ pprintErr i e'-                    ProgramLineComment -> return () -- fail elsewhere-                    _ -> do setErrSpan emptyFC -- FIXME! Propagate it-                                               -- Issue #1576 on the issue tracker.-                                               -- https://github.com/idris-lang/Idris-dev/issues/1576-                            iWarn emptyFC $ pprintErr i e-                  return [])-   where -- load all files, stop if any fail-         tryLoad :: Bool -> IBCPhase -> [IFileType] -> Idris ()-         tryLoad keepstate phase [] = warnTotality >> return ()-         tryLoad keepstate phase (f : fs)-                 = do ist <- getIState-                      let maxline-                            = case toline of-                                Nothing -> Nothing-                                Just l -> case f of-                                            IDR fn -> if any (fmatch fn) inputs-                                                         then Just l-                                                         else Nothing-                                            LIDR fn -> if any (fmatch fn) inputs-                                                          then Just l-                                                          else Nothing-                                            _ -> Nothing-                      loadFromIFile True phase f maxline-                      inew <- getIState-                      -- FIXME: Save these in IBC to avoid this hack! Need to-                      -- preserve it all from source inputs-                      ---                      -- Issue #1577 on the issue tracker.-                      --     https://github.com/idris-lang/Idris-dev/issues/1577-                      let tidata = idris_tyinfodata inew-                      let patdefs = idris_patdefs inew-                      ok <- noErrors-                      if ok then-                            -- The $!! here prevents a space leak on reloading.-                            -- This isn't a solution - but it's a temporary stopgap.-                            -- See issue #2386-                            do when (not keepstate) $ putIState $!! ist-                               ist <- getIState-                               putIState $!! ist { idris_tyinfodata = tidata,-                                                   idris_patdefs = patdefs }-                               tryLoad keepstate phase fs-                          else warnTotality--         ibc (IBC _ _) = True-         ibc _ = False--         fmatch ('.':'/':xs) ys = fmatch xs ys-         fmatch xs ('.':'/':ys) = fmatch xs ys-         fmatch xs ys = xs == ys--         findNewIBC :: IFileType -> Idris (Maybe IFileType)-         findNewIBC i@(IBC _ _) = return (Just i)-         findNewIBC s@(IDR f) = do ist <- get-                                   ibcsd <- valIBCSubDir ist-                                   let ibc = ibcPathNoFallback ibcsd f-                                   ok <- runIO $ doesFileExist ibc-                                   if ok then return (Just (IBC ibc s))-                                         else return Nothing-         findNewIBC s@(LIDR f) = do ist <- get-                                    ibcsd <- valIBCSubDir ist-                                    let ibc = ibcPathNoFallback ibcsd f-                                    ok <- runIO $ doesFileExist ibc-                                    if ok then return (Just (IBC ibc s))-                                          else return Nothing--         -- Like mapM, but give up when there's an error-         mapWhileOK f [] = return []-         mapWhileOK f (x : xs) = do x' <- f x-                                    ok <- noErrors-                                    if ok then do xs' <- mapWhileOK f xs-                                                  return (x' : xs')-                                          else return [x']--idrisMain :: [Opt] -> Idris ()-idrisMain opts =-  do   mapM_ setWidth (opt getConsoleWidth opts)-       let inputs = opt getFile opts-       let quiet = Quiet `elem` opts-       let nobanner = NoBanner `elem` opts-       let idesl = Idemode `elem` opts || IdemodeSocket `elem` opts-       let runrepl = not (NoREPL `elem` opts)-       let verbose = runrepl || Verbose `elem` opts-       let output = opt getOutput opts-       let ibcsubdir = opt getIBCSubDir opts-       let importdirs = opt getImportDir opts-       let bcs = opt getBC opts-       let pkgdirs = opt getPkgDir opts-       -- Set default optimisations-       let optimise = case opt getOptLevel opts of-                        [] -> 2-                        xs -> last xs--       setOptLevel optimise-       let outty = case opt getOutputTy opts of-                     [] -> if Interface `elem` opts then-                              Object else Executable-                     xs -> last xs-       let cgn = case opt getCodegen opts of-                   [] -> Via IBCFormat "c"-                   xs -> last xs-       let cgFlags = opt getCodegenArgs opts--       -- Now set/unset specifically chosen optimisations-       sequence_ (opt getOptimisation opts)-       script <- case opt getExecScript opts of-                   []     -> return Nothing-                   x:y:xs -> do iputStrLn "More than one interpreter expression found."-                                runIO $ exitWith (ExitFailure 1)-                   [expr] -> return (Just expr)-       let immediate = opt getEvalExpr opts-       let port = getPort opts--       when (DefaultTotal `elem` opts) $ do i <- getIState-                                            putIState (i { default_total = DefaultCheckingTotal })-       tty <- runIO isATTY-       setColourise $ not quiet && last (tty : opt getColour opts)----       mapM_ addLangExt (opt getLanguageExt opts)-       setREPL runrepl-       setQuiet (quiet || isJust script || not (null immediate))-       setVerbose verbose-       setCmdLine opts-       setOutputTy outty-       setNoBanner nobanner-       setCodegen cgn-       mapM_ (addFlag cgn) cgFlags-       mapM_ makeOption opts-       -- if we have the --bytecode flag, drop into the bytecode assembler-       case bcs of-         [] -> return ()-         xs -> return () -- runIO $ mapM_ bcAsm xs-       case ibcsubdir of-         [] -> setIBCSubDir ""-         (d:_) -> setIBCSubDir d-       setImportDirs importdirs--       setNoBanner nobanner--       when (not (NoBasePkgs `elem` opts)) $ do-           addPkgDir "prelude"-           addPkgDir "base"-       mapM_ addPkgDir pkgdirs-       elabPrims-       when (not (NoBuiltins `elem` opts)) $ do x <- loadModule "Builtins" (IBC_REPL True)-                                                addAutoImport "Builtins"-                                                return ()-       when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude" (IBC_REPL True)-                                               addAutoImport "Prelude"-                                               return ()-       when (runrepl && not idesl) initScript--       nobanner <- getNoBanner--       when (runrepl &&-             not quiet &&-             not idesl &&-             not (isJust script) &&-             not nobanner &&-             null immediate) $-         iputStrLn banner--       orig <- getIState--       mods <- if idesl then return [] else loadInputs inputs Nothing-       let efile = case inputs of-                        [] -> ""-                        (f:_) -> f--       runIO $ hSetBuffering stdout LineBuffering--       ok <- noErrors-       when ok $ case output of-                    [] -> return ()-                    (o:_) -> idrisCatch (process "" (Compile cgn o))-                               (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)--       case immediate of-         [] -> return ()-         exprs -> do setWidth InfinitelyWide-                     mapM_ (\str -> do ist <- getIState-                                       c <- colourise-                                       case parseExpr ist str of-                                         Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)-                                                                       runIO $ exitWith (ExitFailure 1)-                                         Success e -> process "" (Eval e))-                           exprs-                     runIO exitSuccess---       case script of-         Nothing -> return ()-         Just expr -> execScript expr--       -- Create Idris data dir + repl history and config dir-       idrisCatch (do dir <- getIdrisUserDataDir-                      exists <- runIO $ doesDirectoryExist dir-                      unless exists $ logLvl 1 ("Creating " ++ dir)-                      runIO $ createDirectoryIfMissing True (dir </> "repl"))-         (\e -> return ())--       historyFile <- fmap (</> "repl" </> "history") getIdrisUserDataDir--       when ok $ case opt getPkgIndex opts of-                      (f : _) -> writePkgIndex f-                      _ -> return ()--       when (runrepl && not idesl) $ do---          clearOrigPats-         startServer port orig mods-         runInputT (replSettings (Just historyFile)) $ repl (force orig) mods efile-       let idesock = IdemodeSocket `elem` opts-       when (idesl) $ idemodeStart idesock orig inputs-       ok <- noErrors-       when (not ok) $ runIO (exitWith (ExitFailure 1))-  where-    makeOption (OLogging i)  = setLogLevel i-    makeOption (OLogCats cs) = setLogCats cs-    makeOption TypeCase      = setTypeCase True-    makeOption TypeInType    = setTypeInType True-    makeOption NoCoverage    = setCoverage False-    makeOption ErrContext    = setErrContext True-    makeOption _             = return ()--    addPkgDir :: String -> Idris ()-    addPkgDir p = do ddir <- runIO getIdrisLibDir-                     addImportDir (ddir </> p)-                     addIBC (IBCImportDir (ddir </> p))--runMain :: Idris () -> IO ()-runMain prog = do res <- runExceptT $ execStateT prog idrisInit-                  case res of-                       Left err -> putStrLn $ "Uncaught error: " ++ show err-                       Right _ -> return ()--execScript :: String -> Idris ()-execScript expr = do i <- getIState-                     c <- colourise-                     case parseExpr i expr of-                          Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)-                                                        runIO $ exitWith (ExitFailure 1)-                          Success term -> do ctxt <- getContext-                                             (tm, _) <- elabVal (recinfo (fileFC "toplevel")) ERHS term-                                             res <- execute tm-                                             runIO $ exitSuccess---- | Get the platform-specific, user-specific Idris dir-getIdrisUserDataDir :: Idris FilePath-getIdrisUserDataDir = runIO $ getAppUserDataDirectory "idris"---- | Locate the platform-specific location for the init script-getInitScript :: Idris FilePath-getInitScript = do idrisDir <- getIdrisUserDataDir-                   return $ idrisDir </> "repl" </> "init"---- | Run the initialisation script-initScript :: Idris ()-initScript = do script <- getInitScript-                idrisCatch (do go <- runIO $ doesFileExist script-                               when go $ do-                                 h <- runIO $ openFile script ReadMode-                                 runInit h-                                 runIO $ hClose h)-                           (\e -> iPrintError $ "Error reading init file: " ++ show e)-    where runInit :: Handle -> Idris ()-          runInit h = do eof <- lift . lift $ hIsEOF h-                         ist <- getIState-                         unless eof $ do-                           line <- runIO $ hGetLine h-                           script <- getInitScript-                           c <- colourise-                           processLine ist line script c-                           runInit h-          processLine i cmd input clr =-              case parseCmd i input cmd of-                   Failure (ErrInfo err _) -> runIO $ print (fixColour clr err)-                   Success (Right Reload) -> iPrintError "Init scripts cannot reload the file"-                   Success (Right (Load f _)) -> iPrintError "Init scripts cannot load files"-                   Success (Right (ModImport f)) -> iPrintError "Init scripts cannot import modules"-                   Success (Right Edit) -> iPrintError "Init scripts cannot invoke the editor"-                   Success (Right Proofs) -> proofs i-                   Success (Right Quit) -> iPrintError "Init scripts cannot quit Idris"-                   Success (Right cmd ) -> process [] cmd-                   Success (Left err) -> runIO $ print err--getFile :: Opt -> Maybe String-getFile (Filename str) = Just str-getFile _ = Nothing--getBC :: Opt -> Maybe String-getBC (BCAsm str) = Just str-getBC _ = Nothing--getOutput :: Opt -> Maybe String-getOutput (Output str) = Just str-getOutput _ = Nothing--getIBCSubDir :: Opt -> Maybe String-getIBCSubDir (IBCSubDir str) = Just str-getIBCSubDir _ = Nothing--getImportDir :: Opt -> Maybe String-getImportDir (ImportDir str) = Just str-getImportDir _ = Nothing--getPkgDir :: Opt -> Maybe String-getPkgDir (Pkg str) = Just str-getPkgDir _ = Nothing--getPkg :: Opt -> Maybe (Bool, String)-getPkg (PkgBuild str) = Just (False, str)-getPkg (PkgInstall str) = Just (True, str)-getPkg _ = Nothing--getPkgClean :: Opt -> Maybe String-getPkgClean (PkgClean str) = Just str-getPkgClean _ = Nothing--getPkgREPL :: Opt -> Maybe String-getPkgREPL (PkgREPL str) = Just str-getPkgREPL _ = Nothing--getPkgCheck :: Opt -> Maybe String-getPkgCheck (PkgCheck str) = Just str-getPkgCheck _              = Nothing---- | Returns None if given an Opt which is not PkgMkDoc---   Otherwise returns Just x, where x is the contents of PkgMkDoc-getPkgMkDoc :: Opt          -- ^ Opt to extract-            -> Maybe String -- ^ Result-getPkgMkDoc (PkgMkDoc str) = Just str-getPkgMkDoc _              = Nothing--getPkgTest :: Opt          -- ^ the option to extract-           -> Maybe String -- ^ the package file to test-getPkgTest (PkgTest f) = Just f-getPkgTest _ = Nothing--getCodegen :: Opt -> Maybe Codegen-getCodegen (UseCodegen x) = Just x-getCodegen _ = Nothing--getCodegenArgs :: Opt -> Maybe String-getCodegenArgs (CodegenArgs args) = Just args-getCodegenArgs _ = Nothing--getConsoleWidth :: Opt -> Maybe ConsoleWidth-getConsoleWidth (UseConsoleWidth x) = Just x-getConsoleWidth _ = Nothing---getExecScript :: Opt -> Maybe String-getExecScript (InterpretScript expr) = Just expr-getExecScript _ = Nothing--getPkgIndex :: Opt -> Maybe FilePath-getPkgIndex (PkgIndex file) = Just file-getPkgIndex _ = Nothing--getEvalExpr :: Opt -> Maybe String-getEvalExpr (EvalExpr expr) = Just expr-getEvalExpr _ = Nothing--getOutputTy :: Opt -> Maybe OutputType-getOutputTy (OutputTy t) = Just t-getOutputTy _ = Nothing--getLanguageExt :: Opt -> Maybe LanguageExt-getLanguageExt (Extension e) = Just e-getLanguageExt _ = Nothing--getTriple :: Opt -> Maybe String-getTriple (TargetTriple x) = Just x-getTriple _ = Nothing--getCPU :: Opt -> Maybe String-getCPU (TargetCPU x) = Just x-getCPU _ = Nothing--getOptLevel :: Opt -> Maybe Int-getOptLevel (OptLevel x) = Just x-getOptLevel _ = Nothing--getOptimisation :: Opt -> Maybe (Idris ())-getOptimisation (AddOpt p) = Just $ addOptimise p-getOptimisation (RemoveOpt p) = Just $ removeOptimise p-getOptimisation _ = Nothing--getColour :: Opt -> Maybe Bool-getColour (ColourREPL b) = Just b-getColour _ = Nothing--getClient :: Opt -> Maybe String-getClient (Client x) = Just x-getClient _ = Nothing---- Get the first valid port-getPort :: [Opt] -> PortID-getPort [] = defaultPort-getPort (Port p:xs)-    | all (`elem` ['0'..'9']) p = PortNumber $ fromIntegral (read p)-    | otherwise                 = getPort xs-getPort (_:xs) = getPort xs--opt :: (Opt -> Maybe a) -> [Opt] -> [a]-opt = mapMaybe--ver = showVersion version ++ suffix-        where-            suffix = if gitHash =="" then "" else "-" ++ gitHash--defaultPort :: PortID-defaultPort = PortNumber (fromIntegral 4294)--banner = "     ____    __     _                                          \n" ++-         "    /  _/___/ /____(_)____                                     \n" ++-         "    / // __  / ___/ / ___/     Version " ++ ver ++ "\n" ++-         "  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/      \n" ++-         " /___/\\__,_/_/  /_/____/       Type :? for help               \n" ++-         "\n" ++-         "Idris is free software with ABSOLUTELY NO WARRANTY.            \n" ++-         "For details type :warranty."--warranty = "\n"                                                                          ++-           "\t THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY  \n" ++-           "\t EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     \n" ++-           "\t IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR    \n" ++-           "\t PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE   \n" ++-           "\t LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR   \n" ++-           "\t CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  \n" ++-           "\t SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       \n" ++-           "\t BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n" ++-           "\t WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  \n" ++-           "\t OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n" ++-           "\t IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+ src/Idris/REPL/Commands.hs view
@@ -0,0 +1,76 @@+module Idris.REPL.Commands where++import Idris.Core.TT+import Idris.Colours+import Idris.AbsSyntaxTree++-- | REPL commands+data Command = Quit+             | Help+             | Eval PTerm+             | NewDefn [PDecl] -- ^ Each 'PDecl' should be either a type declaration (at most one) or a clause defining the same name.+             | Undefine [Name]+             | Check PTerm+             | Core PTerm+             | DocStr (Either Name Const) HowMuchDocs+             | TotCheck Name+             | Reload+             | Watch+             | Load FilePath (Maybe Int) -- up to maximum line number+             | ChangeDirectory FilePath+             | ModImport String+             | Edit+             | Compile Codegen String+             | Execute PTerm+             | ExecVal PTerm+             | Metavars+             | Prove Bool Name -- ^ If false, use prover, if true, use elab shell+             | AddProof (Maybe Name)+             | RmProof Name+             | ShowProof Name+             | Proofs+             | Universes+             | LogLvl Int+             | LogCategory [LogCat]+             | Spec PTerm+             | WHNF PTerm+             | TestInline PTerm+             | Defn Name+             | Missing Name+             | DynamicLink FilePath+             | ListDynamic+             | Pattelab PTerm+             | Search [String] PTerm+             | CaseSplitAt Bool Int Name+             | AddClauseFrom Bool Int Name+             | AddProofClauseFrom Bool Int Name+             | AddMissing Bool Int Name+             | MakeWith Bool Int Name+             | MakeCase Bool Int Name+             | MakeLemma Bool Int Name+             | DoProofSearch Bool   -- update file+                             Bool   -- recursive search+                             Int    -- depth+                             Name   -- top level name+                             [Name] -- hints+             | SetOpt Opt+             | UnsetOpt Opt+             | NOP+             | SetColour ColourType IdrisColour+             | ColourOn+             | ColourOff+             | ListErrorHandlers+             | SetConsoleWidth ConsoleWidth+             | SetPrinterDepth (Maybe Int)+             | Apropos [String] String+             | WhoCalls Name+             | CallsWho Name+             | Browse [String]+             | MakeDoc String -- IdrisDoc+             | Warranty+             | PrintDef Name+             | PPrint OutputFmt Int PTerm+             | TransformInfo Name+             -- Debugging commands+             | DebugInfo Name+             | DebugUnify PTerm PTerm
src/Idris/REPL/Parser.hs view
@@ -1,7 +1,6 @@ {-| Module      : Idris.REPL.Parser Description : Parser for the REPL commands.-Copyright   : License     : BSD3 Maintainer  : The Idris Community. -}@@ -21,6 +20,8 @@ import Idris.Help import qualified Idris.Parser as P +import Idris.REPL.Commands+ import Control.Applicative import Control.Monad.State.Strict @@ -520,7 +521,7 @@  cmd_search :: String -> P.IdrisParser (Either String Command) cmd_search = packageBasedCmd-  (P.typeExpr (defaultSyntax { implicitAllowed = True })) Search+  (P.fullExpr (defaultSyntax { implicitAllowed = True })) Search  cmd_proofsearch :: String -> P.IdrisParser (Either String Command) cmd_proofsearch name = do
src/Idris/Reflection.hs view
@@ -84,7 +84,7 @@ reify :: IState -> Term -> ElabD PTactic reify _ (P _ n _) | n == reflm "Intros" = return Intros reify _ (P _ n _) | n == reflm "Trivial" = return Trivial-reify _ (P _ n _) | n == reflm "Instance" = return TCInstance+reify _ (P _ n _) | n == reflm "Implementation" = return TCImplementation reify _ (P _ n _) | n == reflm "Solve" = return Solve reify _ (P _ n _) | n == reflm "Compute" = return Compute reify _ (P _ n _) | n == reflm "Skip" = return Skip@@ -257,10 +257,10 @@         reifySN t [Constant (I i), n]                 | t == reflm "WithN" = WithN i <$> reifyTTName n         reifySN t [n, ss]-                | t == reflm "InstanceN" =+                | t == reflm "ImplementationN" =                   case unList ss of-                    Nothing -> fail "Can't reify InstanceN strings"-                    Just ss' -> InstanceN <$> reifyTTName n <*>+                    Nothing -> fail "Can't reify ImplementationN strings"+                    Just ss' -> ImplementationN <$> reifyTTName n <*>                                  pure [T.pack s | Constant (Str s) <- ss']         reifySN t [n, Constant (Str s)]                 | t == reflm "ParentN" =@@ -275,8 +275,8 @@                 | t == reflm "ElimN" =                   ElimN <$> reifyTTName n         reifySN t [n]-                | t == reflm "InstanceCtorN" =-                  InstanceCtorN <$> reifyTTName n+                | t == reflm "ImplementationCtorN" =+                  ImplementationCtorN <$> reifyTTName n         reifySN t [n1, n2]                 | t == reflm "MetaN" =                   MetaN <$> reifyTTName n1 <*> reifyTTName n2@@ -699,11 +699,11 @@ reflectSpecialName (WithN i n) = reflCall "WithN" [ RConstant (I i)                                                   , reflectName n                                                   ]-reflectSpecialName (InstanceN inst ss) =-  reflCall "InstanceN" [ reflectName inst-                       , mkList (RConstant StrType) $-                           map (RConstant . Str . T.unpack) ss-                       ]+reflectSpecialName (ImplementationN impl ss) =+  reflCall "ImplementationN" [ reflectName impl+                             , mkList (RConstant StrType) $+                                 map (RConstant . Str . T.unpack) ss+                             ] reflectSpecialName (ParentN n s) =   reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))] reflectSpecialName (MethodN n) =@@ -712,8 +712,8 @@   reflCall "CaseN" [reflectFC (unwrapFC fc), reflectName n] reflectSpecialName (ElimN n) =   reflCall "ElimN" [reflectName n]-reflectSpecialName (InstanceCtorN n) =-  reflCall "InstanceCtorN" [reflectName n]+reflectSpecialName (ImplementationCtorN n) =+  reflCall "ImplementationCtorN" [reflectName n] reflectSpecialName (MetaN parent meta) =   reflCall "MetaN" [reflectName parent, reflectName meta] 
src/Idris/TypeSearch.hs view
@@ -30,8 +30,8 @@ import           Data.Traversable                   (traverse)  import Idris.AbsSyntax     (addUsingConstraints, addImpl, getIState, putIState, implicit, logLvl)-import Idris.AbsSyntaxTree (class_instances, ClassInfo, defaultSyntax, eqTy, Idris-                           , IState (idris_classes, idris_docstrings, tt_ctxt, idris_outputmode),+import Idris.AbsSyntaxTree (interface_implementations, InterfaceInfo, defaultSyntax, eqTy, Idris+                           , IState (idris_interfaces, idris_docstrings, tt_ctxt, idris_outputmode),                            implicitAllowed, OutputMode(..), PTerm, toplevel) import Idris.Core.Evaluate (Context (definitions), Def (Function, TyDecl, CaseOp), normaliseC) import Idris.Core.TT       hiding (score)@@ -173,8 +173,8 @@ -- | Asymmetric modifications to keep track of data AsymMods = Mods   { argApp         :: !Int-  , typeClassApp   :: !Int-  , typeClassIntro :: !Int+  , interfaceApp   :: !Int+  , interfaceIntro :: !Int   } deriving (Eq, Show)  @@ -252,19 +252,19 @@ -- The 'Int' represents the position of the argument (1st argument, 2nd, etc.) type ArgsDAG = [((Name, Type), (Int, Set Name))] --- | A list of typeclass constraints-type Classes = [(Name, Type)]+-- | A list of interface constraints+type Interfaces = [(Name, Type)]  -- | The state corresponding to an attempted match of two types. data State = State-  { holes          :: ![(Name, Type)] -- ^ names which have yet to be resolved-  , argsAndClasses :: !(Sided (ArgsDAG, Classes))-     -- ^ arguments and typeclass constraints for each type which have yet to be resolved-  , score     :: !Score -- ^ the score so far-  , usedNames :: ![Name] -- ^ all names that have been used+  { holes             :: ![(Name, Type)] -- ^ names which have yet to be resolved+  , argsAndInterfaces :: !(Sided (ArgsDAG, Interfaces))+     -- ^ arguments and interface constraints for each type which have yet to be resolved+  , score             :: !Score -- ^ the score so far+  , usedNames         :: ![Name] -- ^ all names that have been used   } deriving Show -modifyTypes :: (Type -> Type) -> (ArgsDAG, Classes) -> (ArgsDAG, Classes)+modifyTypes :: (Type -> Type) -> (ArgsDAG, Interfaces) -> (ArgsDAG, Interfaces) modifyTypes f = modifyDag *** modifyList   where   modifyDag = map (first (second f))@@ -273,11 +273,11 @@ findNameInArgsDAG :: Name -> ArgsDAG -> Maybe (Type, Maybe Int) findNameInArgsDAG name = fmap ((snd . fst) &&& (Just . fst . snd)) . find ((name ==) . fst . fst) -findName :: Name -> (ArgsDAG, Classes) -> Maybe (Type, Maybe Int)-findName n (args, classes) = findNameInArgsDAG n args <|> ((,) <$> lookup n classes <*> Nothing)+findName :: Name -> (ArgsDAG, Interfaces) -> Maybe (Type, Maybe Int)+findName n (args, interfaces) = findNameInArgsDAG n args <|> ((,) <$> lookup n interfaces <*> Nothing) -deleteName :: Name -> (ArgsDAG, Classes) -> (ArgsDAG, Classes)-deleteName n (args, classes) = (deleteFromDag n args, filter ((/= n) . fst) classes)+deleteName :: Name -> (ArgsDAG, Interfaces) -> (ArgsDAG, Interfaces)+deleteName n (args, interfaces) = (deleteFromDag n args, filter ((/= n) . fst) interfaces)  tcToMaybe :: TC a -> Maybe a tcToMaybe (OK x) = Just x@@ -287,8 +287,8 @@ inArgTys = map . first . second  -typeclassUnify :: Ctxt ClassInfo -> Context -> Type -> Type -> Maybe [(Name, Type)]-typeclassUnify classInfo ctxt ty tyTry = do+interfaceUnify :: Ctxt InterfaceInfo -> Context -> Type -> Type -> Maybe [(Name, Type)]+interfaceUnify interfaceInfo ctxt ty tyTry = do   res <- tcToMaybe $ match_unify ctxt [] (ty, Nothing) (retTy, Nothing) [] theHoles []   guard $ null (theHoles \\ map fst res)   let argTys' = map (second $ foldr (.) id [ subst n t | (n, t) <- res ]) tcArgs@@ -297,13 +297,13 @@   tyTry' = vToP tyTry   theHoles = map fst nonTcArgs   retTy = getRetTy tyTry'-  (tcArgs, nonTcArgs) = partition (isTypeClassArg classInfo . snd) $ getArgTys tyTry'+  (tcArgs, nonTcArgs) = partition (isInterfaceArg interfaceInfo . snd) $ getArgTys tyTry' -isTypeClassArg :: Ctxt ClassInfo -> Type -> Bool-isTypeClassArg classInfo ty = not (null (getClassName clss >>= flip lookupCtxt classInfo)) where+isInterfaceArg :: Ctxt InterfaceInfo -> Type -> Bool+isInterfaceArg interfaceInfo ty = not (null (getInterfaceName clss >>= flip lookupCtxt interfaceInfo)) where   (clss, args) = unApply ty-  getClassName (P (TCon _ _) className _) = [className]-  getClassName _ = []+  getInterfaceName (P (TCon _ _) interfaceName _) = [interfaceName]+  getInterfaceName _ = []   -- | Compute the power set@@ -345,12 +345,12 @@            <$> flipEqualities ty <*> flipEqualitiesDag xs     startStates (numEqFlips, sndDag, sndRetTy) = do       state <- unifyQueue (State startingHoles-                (Sided (dag1, typeClassArgs1) (sndDag, typeClassArgs2))+                (Sided (dag1, interfaceArgs1) (sndDag, interfaceArgs2))                 (mempty { equalityFlips = numEqFlips }) usedns) [(retTy1, sndRetTy)]       return (score state, state)  -    (dag2, typeClassArgs2, retTy2) = makeDag (uniqueBinders (map fst argNames1) type2)+    (dag2, interfaceArgs2, retTy2) = makeDag (uniqueBinders (map fst argNames1) type2)     argNames2 = map fst dag2     usedns = map fst startingHoles     startingHoles = argNames1 ++ argNames2@@ -376,13 +376,13 @@     ctxt = tt_ctxt istate-  classInfo = idris_classes istate+  interfaceInfo = idris_interfaces istate -  (dag1, typeClassArgs1, retTy1) = makeDag type1+  (dag1, interfaceArgs1, retTy1) = makeDag type1   argNames1 = map fst dag1-  makeDag :: Type -> (ArgsDAG, Classes, Type)+  makeDag :: Type -> (ArgsDAG, Interfaces, Type)   makeDag = first3 (zipWith (\i (ty, deps) -> (ty, (i, deps))) [0..] . reverseDag) .-    computeDagP (isTypeClassArg classInfo) . vToP . unLazy+    computeDagP (isInterfaceArg interfaceInfo) . vToP . unLazy   first3 f (a,b,c) = (f a, b, c)    -- update our state with the unification resolutions@@ -396,14 +396,14 @@     let transScore = fromMaybe 0 (abs <$> ((-) <$> ix1 <*> ix2))     return (inScore (\s -> s { transposition = transposition s + transScore }) state'', (ty1, ty2) : queue)     where-    unresolved = argsAndClasses state+    unresolved = argsAndInterfaces state     inScore f stat = stat { score = f (score stat) }     findArgs = ((,) <$> findName name  (left unresolved) <*> findName name2 (right unresolved)) <|>                ((,) <$> findName name2 (left unresolved) <*> findName name  (right unresolved))     matchnames = [name, name2]     deleteArgs = deleteName name . deleteName name2     state' = state { holes = filter (not . (`elem` matchnames) . fst) (holes state)-                   , argsAndClasses = both (modifyTypes (subst name term) . deleteArgs) unresolved}+                   , argsAndInterfaces = both (modifyTypes (subst name term) . deleteArgs) unresolved}    resolveUnis ((name, term) : xs)     state@(State hs unresolved _ _) = case both (findName name) unresolved of@@ -427,7 +427,7 @@     addScore additions theState = theState { score = let s = score theState in       s { asymMods = asymMods s `mappend` additions } }     state' = state { holes = filter (not . (`elem` toDelete) . fst) hs-                   , argsAndClasses = both (modifyTypes (subst name term) . deleteMany) (argsAndClasses state) }+                   , argsAndInterfaces = both (modifyTypes (subst name term) . deleteMany) (argsAndInterfaces state) }     nextStep = resolveUnis xs state'  @@ -443,19 +443,19 @@     guard $ scoreCriterion (score state')     unifyQueue state' (queue ++ queueAdditions) -  possClassInstances :: [Name] -> Type -> [Type]-  possClassInstances usedns ty = do-    className <- getClassName clss-    classDef <- lookupCtxt className classInfo-    n <- class_instances classDef+  possInterfaceImplementations :: [Name] -> Type -> [Type]+  possInterfaceImplementations usedns ty = do+    interfaceName <- getInterfaceName clss+    interfaceDef <- lookupCtxt interfaceName interfaceInfo+    n <- interface_implementations interfaceDef     def <- lookupCtxt (fst n) (definitions ctxt)     nty <- normaliseC ctxt [] <$> (case typeFromDef def of Just x -> [x]; Nothing -> [])     let ty' = vToP (uniqueBinders usedns nty)     return ty'     where     (clss, _) = unApply ty-    getClassName (P (TCon _ _) className _) = [className]-    getClassName _ = []+    getInterfaceName (P (TCon _ _) interfaceName _) = [interfaceName]+    getInterfaceName _ = []    -- 'Just' if the computation hasn't totally failed yet, 'Nothing' if it has   -- 'Left' if we haven't found a terminal state, 'Right' if we have@@ -477,11 +477,11 @@   -- the search tree. Once we advance in a phase, there should be no going back.   nextSteps :: State -> [State] -  -- Stage 3 - match typeclasses+  -- Stage 3 - match interfaces   nextSteps (State [] unresolved@(Sided ([], c1) ([], c2)) scoreAcc usedns) =     if null results3 then results4 else results3     where-    -- try to match a typeclass argument from the left with a typeclass argument from the right+    -- try to match an interface argument from the left with an interface argument from the right     results3 =          catMaybes [ unifyQueue (State []          (Sided ([], deleteFromArgList n1 c1)@@ -489,31 +489,31 @@          scoreAcc usedns) [(ty1, ty2)]      | (n1, ty1) <- c1, (n2, ty2) <- c2, let subst2for1 = psubst n2 (P Bound n1 ty1)] -    -- try to hunt match a typeclass constraint by replacing it with an instance+    -- try to hunt match an interface constraint by replacing it with an implementation     results4 = [ State [] (both (\(cs, _, _) -> ([], cs)) sds)                (scoreAcc `mappend` Score 0 0 (both (\(_, amods, _) -> amods) sds))                (usedns ++ sided (++) (both (\(_, _, hs) -> hs) sds))                | sds <- allMods ]       where       allMods = parallel defMod mods-      mods :: Sided [( Classes, AsymMods, [Name] )]-      mods = both (instanceMods . snd) unresolved-      defMod :: Sided (Classes, AsymMods, [Name])+      mods :: Sided [( Interfaces, AsymMods, [Name] )]+      mods = both (implementationMods . snd) unresolved+      defMod :: Sided (Interfaces, AsymMods, [Name])       defMod = both (\(_, cs) -> (cs, mempty , [])) unresolved       parallel :: Sided a -> Sided [a] -> [Sided a]       parallel (Sided l r) (Sided ls rs) = map (flip Sided r) ls ++ map (Sided l) rs-      instanceMods :: Classes -> [( Classes , AsymMods, [Name] )]-      instanceMods classes = [ ( newClassArgs, mempty { typeClassApp = 1 }, newHoles )-                      | (_, ty) <- classes-                      , inst <- possClassInstances usedns ty-                      , newClassArgs <- maybeToList $ typeclassUnify classInfo ctxt ty inst-                      , let newHoles = map fst newClassArgs ]+      implementationMods :: Interfaces -> [( Interfaces , AsymMods, [Name] )]+      implementationMods interfaces = [ ( newInterfaceArgs, mempty { interfaceApp = 1 }, newHoles )+                                      | (_, ty) <- interfaces+                                      , impl <- possInterfaceImplementations usedns ty+                                      , newInterfaceArgs <- maybeToList $ interfaceUnify interfaceInfo ctxt ty impl+                                      , let newHoles = map fst newInterfaceArgs ]     -- Stage 1 - match arguments   nextSteps (State hs (Sided (dagL, c1) (dagR, c2)) scoreAcc usedns) = results where -    results = concatMap takeSomeClasses results1+    results = concatMap takeSomeInterfaces results1      -- we only try to match arguments whose names don't appear in the types     -- of any other arguments@@ -530,20 +530,20 @@   -  -- Stage 2 - simply introduce a subset of the typeclasses-  -- we've finished, so take some classes-  takeSomeClasses (State [] unresolved@(Sided ([], _) ([], _)) scoreAcc usedns) =-    map statesFromMods . prod $ both (classMods . snd) unresolved+  -- Stage 2 - simply introduce a subset of the interfaces+  -- we've finished, so take some interfaces+  takeSomeInterfaces (State [] unresolved@(Sided ([], _) ([], _)) scoreAcc usedns) =+    map statesFromMods . prod $ both (interfaceMods . snd) unresolved     where     swap (Sided l r) = Sided r l-    statesFromMods :: Sided (Classes, AsymMods) -> State-    statesFromMods sides = let classes = both (\(c, _) -> ([], c)) sides+    statesFromMods :: Sided (Interfaces, AsymMods) -> State+    statesFromMods sides = let interfaces = both (\(c, _) -> ([], c)) sides                                mods    = swap (both snd sides) in-      State [] classes (scoreAcc `mappend` (mempty { asymMods = mods })) usedns-    classMods :: Classes -> [(Classes, AsymMods)]-    classMods cs = let lcs = length cs in-      [ (cs', mempty { typeClassIntro = lcs - length cs' }) | cs' <- subsets cs ]+      State [] interfaces (scoreAcc `mappend` (mempty { asymMods = mods })) usedns+    interfaceMods :: Interfaces -> [(Interfaces, AsymMods)]+    interfaceMods cs = let lcs = length cs in+      [ (cs', mempty { interfaceIntro = lcs - length cs' }) | cs' <- subsets cs ]     prod :: Sided [a] -> [Sided a]     prod (Sided ls rs) = [Sided l r | l <- ls, r <- rs]   -- still have arguments to match, so just be the identity-  takeSomeClasses s = [s]+  takeSomeInterfaces s = [s]
src/Util/DynamicLinker.hs view
@@ -132,6 +132,8 @@                           Left (ex :: IOException) -> mapMFirst f as                           Right res -> return $ Just res +-- Both regexes copyright 2009-2011 Howard B. Golden, CJ van den Berg and Ian+-- Lynagh. From the Glasgow Haskell Compiler. BSD licensed. invalidLibRegex :: Regex invalidLibRegex = makeRegex "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short)" 
src/Util/Net.hs view
@@ -8,13 +8,14 @@ module Util.Net (listenOnLocalhost, listenOnLocalhostAnyPort) where  import Network hiding (socketPort)-import Network.Socket hiding (sClose, PortNumber)+import Network.Socket hiding (sClose) import Network.BSD (getProtocolNumber) import Control.Exception (bracketOnError)  -- Copied from upstream impl of listenOn -- bound to localhost interface instead of iNADDR_ANY-listenOnLocalhost (PortNumber port) = do+listenOnLocalhost :: PortNumber -> IO Socket+listenOnLocalhost port = do     proto <- getProtocolNumber "tcp"     localhost <- inet_addr "127.0.0.1"     bracketOnError@@ -27,6 +28,7 @@           return sock       ) +listenOnLocalhostAnyPort :: IO (Socket, PortNumber) listenOnLocalhostAnyPort = do     proto <- getProtocolNumber "tcp"     localhost <- inet_addr "127.0.0.1"
src/Util/System.hs view
@@ -37,7 +37,8 @@  #ifdef FREESTANDING import Tools_idris-import System.FilePath (isAbsolute, dropFileName)+import Data.List (intercalate)+import System.FilePath (isAbsolute, dropFileName, searchPathSeparator) import System.Directory (doesDirectoryExist) import System.Environment (getEnv, setEnv, getExecutablePath) #endif@@ -109,11 +110,10 @@                                     if absolute                                        then tcDir                                        else dropFileName exePath ++ tcDir-                        let pathSep = if isWindows then ";" else ":"                         present <- doesDirectoryExist target-                        when present-                            $ do newPath <- return $ target ++ pathSep ++ path-                                 setEnv "PATH" newPath+                        when present $ do+                          newPath <- return $ intercalate [searchPathSeparator] [target, path]+                          setEnv "PATH" newPath #else setupBundledCC = return () #endif
+ stack-shell.nix view
@@ -0,0 +1,31 @@+with (import <nixpkgs> {});++let+  # MUST match resolver in stack.yaml+  resolver = haskell.packages.lts-7_0.ghc;++  native_libs = [+    libffi+    zlib+    ncurses+    gmp+    pkgconfig+  ] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [+    Cocoa+    CoreServices+  ]);++in stdenv.mkDerivation {++  name = "idrisBuildEnv";++  buildInputs = [ resolver ] ++ native_libs;++  STACK_IN_NIX_EXTRA_ARGS = builtins.foldl'+    (acc: lib:+      " --extra-lib-dirs=${lib}/lib --extra-include-dirs=${lib}/include" + acc)+    "" native_libs;++  # Needed if one wants to use ghci, due to https://ghc.haskell.org/trac/ghc/ticket/11042+  LD_LIBRARY_PATH = builtins.concatStringsSep ":" (map (lib: lib.out + "/lib") native_libs);+}
stack.yaml view
@@ -1,4 +1,4 @@-resolver: lts-6.9+resolver: lts-7.0  packages:   - location: .@@ -10,7 +10,6 @@  extra-deps:   - libffi-0.1-  - trifecta-1.6  nix:   enable: false
+ test/README.md view
@@ -0,0 +1,165 @@+# Idris' Testing Suite++## Running the test suite++Do `make test_c` or `make test_js`. It will run the tests in parallel and through `cabal test`.+You can also manually call `cabal test` or `stack test`.++### Passing arguments++#### To the test program++You can pass arguments to the test program. For example, to pass the `--help` argument:++```+# Via make+make TEST-ARGS="--help" test_c+# Via cabal+cabal test --test-options="--help"+# Via stack+stack test --test-arguments="--help"+```++Try it to learn more about the other arguments you can provide. Two are of particular interest: `--node` to test against the Node code generator and `--pattern <regex>` to only run the test that match the provided `<regex>`.++#### To idris++You can pass arguments to idris in each of its invocation by the tests. There are two ways to this. You can either modify the `idrisFlags` term in `TestRun`, or set the `$IDRIS` environment variable accordingly++### Specifying the number of parallel jobs++With make, the test suite runs in parallel by default. You can specify the number of threads with `TEST-JOBS`. For stack and cabal, you need to explicitly enable parallelism as you would do with any other GHC-compiled executable. Examples:++```+# Two test jobs via make+make TEST-JOBS=2 test_c+# Two test jobs via cabal+cabal test --test-options="+RTS -N2 -RTS"+# Two test jobs via stack+stack test --test-arguments="+RTS -N2 -RTS"+```++### Running only previously failed tests++Because of the `--rerun-update` option, `make test_c` will create a `.tasty-rerun-log` file in the root directory of the project. Each time the test suite is run, the file will be written with the result of the tests. The next time you do `make test`, you can specify the `rerun-filter` argument to, for example, only run previously failed tests. Valid values are given in the `--help`.++## Extending the test suite++### Content of the directory++To each test there shall be a folder that holds at least a bash script `run` and a golden file `expected`. When running the test suite, the standard output of the script is compared against the golden file. Any mismatch is reported as a failure.++The name of a test folder is the identifier of the *test family* followed by a three digit number. A test family gathers related tests.++Add to that four top level files:++- The program `TestRun.hs` that runs the test suite+- A Haskell module `TestData.hs` with the metadata for each test+- The Perl script `mktest.pl` to ease the creation of a new test+- This `README.md`++### Test families++Tests are categorised with the following test families (and their identifiers):+++ *basic*:          Basic language features, some complete programs++ *bignum*:         Bignums and GMP++ *bounded*:        Bounds testing for bits++ *corecords*:      Tests for corecord++ *delab*:          De-elaboration tests++ *directives*:     Tests for directives++ *disambig*:       Disambiguaton tests++ *docs*:           Testing documentation functionality++ *dsl*:            Embedded DSLs and features to support DSL development++ *effects*:        Effects package++ *error*:          Error messages and error reflection++ *ffi*:            FFI calls, including type providers++ *folding*         Testing some folds++ *idrisdoc*:       Documentation tool functionality++ *interactive*:    Interactive editing, proof search++ *interfaces*:     Testing interfaces.++ *io*:             IO monad++ *literate*:       `.lidr` files; literate programming++ *meta*:           Meta-programming++ *pkg*:            Packages++ *primitives*:     Primitive types++ *proof*:          Theorem proving, tactics++ *proofsearch*:    Proof search++ *pruviloj*:       Elaborator reflection++ *quasiquote*:     Quasiquotations++ *records*:        Records++ *reg*:            Regression tests, covering previous bug fixes++ *regression*:     Regression tests, covering previous bug fixes++ *sourceLocation*: Interaction with files from Idris++ *sugar*:          Syntactic sugar, syntax extensions++ *syntax*:         Syntax extensions++ *tactics*:        Testing for tactics++ *totality*:       Totality checking++ *tutorial*:       Examples from the tutorial++ *unique*:         Uniqueness types++ *universes*:      Universes++ *views*:          Views and covering functions++### Adding a test family++1. Choose an available identifier for your test family. It should be short+and somewhat self-explanatory.+2. Add it in the `README.md` file, i.e. just above.+3. Add it in `TestData.hs`, in the `testFamiliesData` list. Say the chosen identifier is `foo`. You should append to the list `("foo", "A proper name for foo", [ ])`. The empty list will be replaced with the metadata of each test in the family.+4. Add your tests.++### Adding a test++1. Choose the family your test shall belong to and remember its identifier.+2. Pick the next available integer in the test family. It will be the index.+3. Say the family's identifier is `foo` and the index is `42`. You should call `./mktest.pl foo042` ; this will create the directory and a simple `run` script.+4. Modify the `run` script to your liking. If you want to call the idris executable, write `${IDRIS:-idris} $@`.+5. Add any file you may need in the directory. If they don't end in `.idr`, you should remember them for the next step.+6. Add your test in `TestData.hs`. Each family has a list of `(Index, CompatCodegen)`.  See the next section for the available values in `CompatCodegen`. In most cases, you should write `( 42, ANY)`.+7. Generate the `expected` file by doing:+    ```+    # Using cabal+    cabal test --test-options="--pattern foo042 --accept"+    # Using stack+    stack test --test-arguments="--pattern foo042 --accept"+    ```+8. Check the content of `expected`. Maybe the test didn't do what you thought it would. Fix and go back to 7 until it's ok.+9. Add under `Extra-source-files` in `idris.cabal` the patterns that match the folder's content. If you forget this, your test will fail in Travis CI. With the previous example, it should be at least:+    ```+    test/foo042/run+    test/foo042/expected+    test/foo042/*.idr+    ```++### Specifying compatible backends++Some tests only make sense with specific code generators. Others don't generate code. You need to supply this information in `testFamiliesData`. Available values+for the compatible backends are:++- `ANY`: choose this if your test will work with any code generator+- `C_CG`: choose this to only test against the C code generator+- `JS_CG`: choose this to only test against the Node code generator+- `NONE`: choose this if you don't want your test to be run with multiple code+generators (mainly for tests that only perform type checking)++Currently, `NONE` has the same effect as `ANY`, but this will change.++### Removing a test++1. Delete the corresponding directory+2. Remove the corresponding line in the definition of `testFamiliesData` in `TestData.hs`++### Updating golden files++To update the `expected` file for every test, do one of the following:++```+# Using make+make test_update+# Using cabal+cabal test --test-options="--accept"+# Using stack+stack test --test-arguments="--accept"+```++"Accepted" tests are the ones that update the golden file. A test can still fail if the `run` script itself crashes.
test/TestData.hs view
@@ -111,16 +111,19 @@       (  5, ANY  ),       (  6, ANY  ),       (  7, ANY  ),-      (  8, ANY  )]),+      (  8, ANY  ),+      (  9, ANY  )]),   ("ffi",             "FFI",-    [ (  1, ANY  ),-      (  2, ANY  ),-      (  3, ANY  ),-      (  4, ANY  ),-      (  5, ANY  ),-      (  6, C_CG ),-      (  7, C_CG ),-      (  8, C_CG )]),+    [ (  1, ANY  )+    , (  2, ANY  )+    , (  3, ANY  )+    , (  4, ANY  )+    , (  5, ANY  )+    , (  6, C_CG )+    , (  7, C_CG )+    , (  8, C_CG )+    , (  9, C_CG )+    ]),   ("folding",         "Folding",     [ (  1, ANY  )]),   ("idrisdoc",        "Idris documentation",@@ -173,7 +176,8 @@       (  3, ANY  ),       (  4, ANY  ),       (  5, ANY  ),-      (  6, ANY )]),+      (  6, ANY  ),+      (  7, ANY  )]),   ("prelude",         "Prelude",     [ (  1, ANY  )]),   ("primitives",      "Primitive types",@@ -215,48 +219,30 @@       (  5, ANY  )]),   ("reg",             "Regressions",     [ (  2, ANY  ),-      (  3, ANY  ),       (  4, ANY  ),       (  5, ANY  ),-      (  6, ANY  ),-      (  7, ANY  ),-      ( 10, ANY  ),       ( 13, ANY  ),       ( 16, ANY  ),       ( 17, ANY  ),-      ( 18, ANY  ),       ( 20, ANY  ),-      ( 23, ANY  ),       ( 24, ANY  ),       ( 25, ANY  ),       ( 27, ANY  ),-      ( 28, ANY  ),       ( 29, C_CG ),       ( 31, ANY  ),       ( 32, ANY  ),-      ( 34, ANY  ),-      ( 35, ANY  ),       ( 39, ANY  ),       ( 40, ANY  ),       ( 41, ANY  ),       ( 42, ANY  ),-      ( 44, ANY  ),       ( 45, ANY  ),       ( 48, ANY  ),-      ( 49, ANY  ),-      ( 50, ANY  ),       ( 52, C_CG ),-      ( 54, ANY  ),-      ( 55, ANY  ),-      ( 56, ANY  ),       ( 67, ANY  ),-      ( 68, ANY  ),-      ( 69, ANY  ),-      ( 70, ANY  ),-      ( 72, ANY  ),       ( 75, ANY  )]),-  ("regression",      "Regression (loner)",-    [ (  1 , ANY  )]),+  ("regression",      "Regression",+    [ (  1 , ANY  ),+      (  2 , ANY  )]),   ("sourceLocation",  "Source location",     [ (  1 , ANY  )]),   ("sugar",           "Syntactic sugar",@@ -285,7 +271,9 @@       ( 12, ANY  ),       ( 13, ANY  ),       ( 14, ANY  ),-      ( 15, ANY  )]),+      ( 15, ANY  ),+      ( 16, ANY  ),+      ( 17, ANY  )]),   ("tutorial",        "Tutorial examples",     [ (  1, ANY  ),       (  2, ANY  ),@@ -296,8 +284,7 @@       (  7, C_CG )]),   ("unique",          "Uniqueness types",     [ (  1, ANY  ),-      (  2, ANY  ),-      (  3, ANY  )]),+      (  4, ANY  )]),   ("universes",       "Universes",     [ (  1, ANY  ),       (  2, ANY  )]),
test/TestRun.hs view
@@ -1,17 +1,15 @@ module Main where  import Control.Monad+import Data.Char (isLetter) import Data.Typeable import Data.Proxy import Data.List-import Data.Map.Strict as Map-import Data.IntSet as ISet-import Data.IntMap as IMap-import qualified Data.ByteString as BS-import qualified Data.ByteString.Char8 as BSC+import qualified Data.IntMap as IMap  import System.Directory import System.Environment+import System.Exit import System.Process import System.Info import System.IO@@ -19,7 +17,6 @@ import Options.Applicative import Test.Tasty import Test.Tasty.Golden-import Test.Tasty.Golden.Advanced import Test.Tasty.Runners import Test.Tasty.Options import Test.Tasty.Ingredients.Rerun@@ -51,7 +48,7 @@   parseValue = fmap NodeOpt . safeRead   optionName = return nodeArg   optionHelp = return nodeHelp-  optionCLParser = fmap NodeOpt $ switch (long nodeArg <> help nodeHelp)+  optionCLParser = NodeOpt <$> switch (long nodeArg <> help nodeHelp)  ingredients :: [Ingredient] ingredients = defaultIngredients ++@@ -63,43 +60,16 @@ -- Compare a given file contents against the golden file contents -- A ripoff of goldenVsFile from Tasty.Golden test :: String -> String -> IO () -> TestTree-test name path act =-  goldenTest name (readFile ref) (act >> readFile new) cmp upd-    where-      ref = path </> "expected"-      new = path </> "output"-      cmp x y = return $ if normalize x == normalize y then Nothing-                                   else Just $ printDiff (ref, x) (new, y)-      upd = writeFile ref-      -- just pretend that backslashes are slashes for comparison-      -- purposes to avoid path problems, so don't write any tests-      -- that depend on that distinction in other contexts.-      -- Also compare CRLF and LF as equal, fixes a weird corner case-      -- on Mac where basic010 and reg039 produces CRLF-      normalize [] = []-      normalize ('\r':'\n':xs) = '\n' : normalize xs-      normalize ('\\':'\\':xs) = '/' : normalize xs-      normalize ('\\':xs) = '/' : normalize xs-      normalize (x : xs) = x : normalize xs----- Takes the filepath and content of `expected` and `output`--- and formats an error message stating their difference-printDiff :: (String, String) -> (String, String) -> String-printDiff (ref, x) (new, y) =-  let printContent cnt =-        if Data.List.null cnt-           then " is empty...\n"-           else " is: \n" ++ unlines (fmap ((++) "  ") (lines cnt))-   in-     "Test mismatch!\n" ++-       "Golden file " ++ ref ++ printContent x ++-       "However, " ++ new ++ printContent y+test testName path = goldenVsFileDiff testName diff ref output+  where+    ref = path </> "expected"+    output = path </> "output"+    diff ref new = ["diff", "--strip-trailing-cr", "-u", new, ref]  -- Should always output a 3-charater string from a postive Int indexToString :: Int -> String indexToString index = let str = show index in-                          (replicate (3 - length str) '0') ++ str+                          replicate (3 - length str) '0' ++ str  -- Turns the collection of TestFamily into actual tests usable by Tasty mkGoldenTests :: [TestFamily] -> Flags -> TestTree@@ -121,15 +91,20 @@ -- this thing. runTest :: String -> Flags -> IO () runTest path flags = do-  let run = (proc "bash" ("run" : flags)) {cwd = Just path,-                                           std_out = CreatePipe,-                                           std_err = CreatePipe}+  let run = (proc "bash" ("run" : flags)) {cwd = Just path}   (_, output, error_out) <- readCreateProcessWithExitCode run ""-  writeFile (path </> "output") output-  hPutStrLn stderr error_out+  writeFile (path </> "output") (normalise output)+  when (error_out /= "") $ hPutStrLn stderr ("\nError: " ++ path ++ "\n" ++ error_out)+    where+      -- Normalise paths e.g. '.\foo.idr' to './foo.idr'.+      -- Also embedded paths e.g. ".\\Prelude\\List.idr" to "./Prelude/List.idr".+      normalise ('.' : '\\' : c : xs) | isLetter c  = '.' : '/' : c : normalise xs+      normalise ('\\':'\\':xs) = '/' : normalise xs+      normalise (x : xs) = x : normalise xs+      normalise [] = []  main :: IO ()-main = do+main =   defaultMainWithIngredients ingredients $     askOption $ \(NodeOpt node) ->       let (codegen, flags) = if node then (JS, ["--codegen", "node"])
test/base001/run view
@@ -1,10 +1,12 @@ #!/usr/bin/env bash +set -u+ if [[ ${OSTYPE} = 'msys' ]]; then   cat expected # skip this test on Windows else-  ${IDRIS:-idris} $@ --build base001.ipkg | grep -v 'make.*:'-  ./base001+  ${IDRIS:-idris} "$@" --build base001.ipkg | grep -v 'make.*:'+  ./base001 2>&1 | grep -v '^sh:.*\./does-not-exist:'   make clean | grep -v 'make.*:'-  rm -f *.ibc base001+  rm -f -- *.ibc base001 fi
test/basic006/expected view
@@ -1,5 +1,4 @@-test020a.idr:16:18:-When checking right hand side of foo with expected type+test020a.idr:16:18:When checking right hand side of foo with expected type         List a  When checking an application of function Prelude.List.reverse:
test/basic008/test036.idr view
@@ -10,8 +10,8 @@ doTest : Maybe Nat doTest = do   a <- Nothing-  unused a (return 3)- `maybechoice` return 2+  unused a (pure 3)+ `maybechoice` pure 2  main : IO () main = putStrLn . show $ doTest
test/basic009/expected view
@@ -1,8 +1,7 @@ MAIN-PASS Faulty.idr:6:9-12:WARNING: num is bound as an implicit 	Did you mean to refer to A.num?-Faulty.idr:7:7:-When checking right hand side of fault with expected type+Faulty.idr:7:7:When checking right hand side of fault with expected type         num = 0  Type mismatch between
test/basic010/run view
@@ -1,41 +1,10 @@ #!/usr/bin/env bash --declare -a extraargs-for arg in "$@"-do-    extraargs=("${extraargs[@]}" "'$arg'")-done--if (which timeout&>/dev/null); then-    timeout 10 ${IDRIS:-idris} $@ Main.idr --nocolour --check --warnreach -o basic010-    timeout 5  ./basic010-else-    # From http://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting-    # Here copied from reg039.-    #-    # Executes command with a timeout-    # Params:-    #   $1 timeout in seconds-    #   $2 command-    # Returns 1 if timed out 0 otherwise-    timeout() {--        time=$1--        # start the command in a subshell to avoid problem with pipes-        # (spawn accepts one command)-        command="/bin/sh -c \"$2\""--        expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"+set -eu -        if [ $? = 1 ] ; then-            echo "Timeout after ${time} seconds"-        fi+TIMEOUT=../scripts/timeout -    }+$TIMEOUT 10 "${IDRIS:-idris}" "$@" Main.idr --nocolour --check --warnreach -o basic010+$TIMEOUT 5  ./basic010 -    timeout 10 "${IDRIS:-idris} ${extraargs[*]} Main.idr --nocolour --check --warnreach -o basic010"-    timeout 5  "./basic010"-fi-rm -f *.ibc basic010+rm -f -- *.ibc basic010
test/basic011/basic011.idr view
@@ -13,4 +13,8 @@           printLn $ hash (the Bits64 3)           printLn $ hash (the Int 3)           printLn $ hash (the Integer 3)+          printLn $ divB8 10 255+          printLn $ divB16 10 65535+          printLn $ divB32 10 4294967295+          printLn $ divB64 10 18446744073709551615 
test/basic011/expected view
@@ -8,3 +8,7 @@ 6EA049D797FA18D6 6EA049D797FA18D6 6EA049D797FA18D6+00+0000+00000000+0000000000000000
test/basic018/expected view
@@ -2,8 +2,7 @@ 	Did you mean to refer to Main.thing? basic018.idr:12:8-13:WARNING: thing is bound as an implicit 	Did you mean to refer to Main.thing?-basic018.idr:13:6:-When checking right hand side of test with expected type+basic018.idr:13:6:When checking right hand side of test with expected type         thing = S 41  Type mismatch between
test/delab001/expected view
@@ -5,8 +5,8 @@ bar : Nat -> String -> String bar x y = case x of             0 => y-            S _ => (y ++ y)+            S _ => y ++ y append : List a -> List a -> List a append xs ys = case xs of                  [] => ys-                 (x :: xs) => (x :: (append xs ys))+                 x :: xs => x :: append xs ys
test/directives001/expected view
@@ -6,9 +6,7 @@ To be replaced with `Bar`. directives001.idr:15:7:Use of deprecated name directives001.Foo To be replaced with `Bar`.-directives001.idr:26:8:-Use of a fragile construct directives001.mkBar+directives001.idr:26:8:Use of a fragile construct directives001.mkBar How `Bar`s are to be created is still being discussed, `mkBar` is subject to change.-directives001.idr:26:8:-Use of a fragile construct directives001.mkBar+directives001.idr:26:8:Use of a fragile construct directives001.mkBar How `Bar`s are to be created is still being discussed, `mkBar` is subject to change.
test/docs002/docs002.idr view
@@ -4,8 +4,8 @@ %language TypeProviders  getType : Int -> IO (Provider Type)-getType 0 = return (Provide Int)-getType _ = return (Provide Bool)+getType 0 = pure (Provide Int)+getType _ = pure (Provide Bool)  ||| Some documentation %provide (T1 : Type) with getType 0
test/docs003/expected view
@@ -6,8 +6,7 @@  Methods:     map : Functor f => (func : a -> b) -> f a -> f b-        Apply a function across everything of type 'a' in a-        parameterised type+        Apply a function across everything of type 'a' in a parameterised type                  The function is Total Implementations:@@ -29,11 +28,11 @@ Child interfaces:     Traversable f     Applicative f-Named instance:+Named implementation:     docs003.mine : Functor List                  -Named instance:+Named implementation:     docs003.another : Functor List         More functors!         
test/dsl001/expected view
@@ -1,2 +1,14 @@ 24 12+testFac : Int+testFac = PE_interp_f79b3e31 [] (PE_fromInteger_a0377313 4)+PE_interp_f79b3e31 : Env G -> Int -> Int+PE_interp_f79b3e31 (3arg) = \x =>+                              ifThenElse (PE_==_a03270d8 x+                                                         (PE_fromInteger_a0377313 0))+                                         (Delay (PE_fromInteger_a0377313 1))+                                         (Delay (PE_*_a725d5d6 (PE_interp_f79b3e31 (x ::+                                                                                    (3arg))+                                                                                   (PE_-_a71cf640 x+                                                                                                  (PE_fromInteger_a0377313 1)))+                                                               x))
+ test/dsl001/input view
@@ -0,0 +1,2 @@+:printdef testFac+:printdef PE_interp_f79b3e31
test/dsl001/run view
@@ -1,4 +1,5 @@ #!/usr/bin/env bash ${IDRIS:-idris} $@ test001.idr -o test001 ./test001+${IDRIS:-idris} $@ test001.idr --quiet < input rm -f test001 test001.ibc
test/dsl001/test001.idr view
@@ -35,6 +35,7 @@       If  : Expr G TyBool -> Expr G a -> Expr G a -> Expr G a       Bind : Expr G a -> (interpTy a -> Expr G b) -> Expr G b +  %static   lam_ : TTName -> Expr (a :: G) t -> Expr G (TyFun a t)   lam_ _ = Lam 
test/dsl002/Resimp.idr view
@@ -117,12 +117,12 @@                 Res gam (update gam p c) t        While  : Res gam gam (R Bool) ->                 Res gam gam (R ()) -> Res gam gam (R ())-       Return : a -> Res gam gam (R a)+       Pure : a -> Res gam gam (R a)        (>>=)  : Res gam gam'  (R a) -> (a -> Res gam' gam'' (R t)) ->                 Res gam gam'' (R t)    ioret : a -> IO a-  ioret = return+  ioret = pure    interp : Env gam -> %static (e : Res gam gam' t) ->            (Env gam' -> interpTy t -> IO u) -> IO u@@ -133,10 +133,10 @@                    (\env', scope' => k (envTail env') scope')   interp env (Update method x) k       = do x' <- getUpdater (method (envLookup x env))-           k (envUpdateVal x x' env) (return ())+           k (envUpdateVal x x' env) (pure ())   interp env (Use method x) k       = do x' <- getReader (method (envLookup x env))-           k env (return x')+           k env (pure x')   interp env (Lift io) k      = k env io   interp env (Check x left right) k =@@ -148,12 +148,12 @@           (\env', result =>              do r <- result                 if (not r)-                   then (k env' (return ()))+                   then (k env' (pure ()))                    else (interp env' body                         (\env'', body' =>                            do v <- body' -- make sure it's evalled                               interp env'' (While test body) k )))-  interp env (Return v) k = k env (return v)+  interp env (Pure v) k = k env (pure v)   interp env (v >>= f) k      = interp env v (\env', v' => do n <- v'                                      interp env' (f n) k)
test/dsl002/test014.idr view
@@ -16,16 +16,16 @@  open : String -> (p:Purpose) -> Creator (Either () (FILE p)) open fn p = ioc (do Right h <- fopen fn (pstring p)-                       | Left err => return (Left ())-                    return (Right (OpenH h)))+                       | Left err => pure (Left ())+                    pure (Right (OpenH h)))  close : FILE p -> Updater () close (OpenH h) = iou (closeFile h)  readLine : FILE Reading -> Reader String readLine (OpenH h) = ior (do Right str <- fGetLine h-                                   | return ""-                             return str)+                                   | pure ""+                             pure str)  eof : FILE Reading -> Reader Bool eof (OpenH h) = ior (fEOF h)
test/dsl003/expected view
@@ -1,2 +1,2 @@-ForAll INT (ForAll INT (ItHolds (Var (FS FZ) === Var FZ))) : Spec [] Refl : ARR BOOL (ARR INT UNIT) = ARR BOOL (ARR INT UNIT)+ForAll INT (ForAll INT (ItHolds (Var (FS FZ) === Var FZ))) : Spec []
test/dsl004/Door0.idr view
@@ -21,7 +21,7 @@      Close : DoorH OPEN -> DoorCmd (DoorH CLOSED)  data DoorLang : Type -> Type where-     Return : a -> DoorLang a+     Pure : a -> DoorLang a      Action : DoorCmd a -> DoorLang a      (>>=) : DoorLang a -> (a -> DoorLang b) -> DoorLang b @@ -29,5 +29,5 @@ testProg h = do h <- Action (Knock h)                 h <- Action (Open h)                 h <- Action (Close h)-                Return ()+                Pure () 
test/dsl004/Door1.idr view
@@ -21,7 +21,7 @@      Close : DoorH OPEN -> DoorCmd (DoorH CLOSED)  data DoorLang : AnyType -> AnyType where-     Return : {a : AnyType} -> a -> DoorLang a+     Pure : {a : AnyType} -> a -> DoorLang a      Action : DoorCmd a -> DoorLang a      (>>=) : DoorLang a -> (a -> DoorLang b) -> DoorLang b @@ -33,5 +33,5 @@ testProg h = with Main, Show do -- h <- Knock h                 h <- Open h                 -- h <- Close h-                Return ()+                Pure () 
test/dsl004/Door2.idr view
@@ -19,7 +19,7 @@      Close : DoorH OPEN -> DoorCmd (DoorH CLOSED)  data DoorLang : AnyType -> AnyType where-     Return : a -> DoorLang a+     Pure : a -> DoorLang a      Action : DoorCmd a -> DoorLang a      (>>=) : DoorLang a -> (a -> DoorLang b) -> DoorLang b @@ -33,5 +33,5 @@                 (True @@ h) <- Action (Open h)                       | (False @@ h) => testProg h                  h <- Action (Close h)-                Return ()+                Pure () 
test/dsl004/Door3.idr view
@@ -18,13 +18,13 @@      Close : DoorH OPEN -> DoorCmd (DoorH CLOSED)  data DoorLang : AnyType -> AnyType where-     Return : {a : AnyType} -> a -> DoorLang a+     Pure : {a : AnyType} -> a -> DoorLang a      Action : DoorCmd a -> DoorLang a      (>>=) : DoorLang a -> (a -> DoorLang b) -> DoorLang b  testProg : DoorH CLOSED -> DoorLang (DoorH CLOSED) testProg h = do h <- Action (Knock h)                 (True @@ h) <- Action (Open h) -                   | (False @@ h) => Return h+                   | (False @@ h) => Pure h                 Action (Close h) 
test/effects001/test021a.idr view
@@ -22,12 +22,12 @@ eval (Var x) = do vs <- get                   case lookup x vs of                         Nothing => raise ("No such variable " ++ x)-                        Just val => return val-eval (Val x) = return x+                        Just val => pure val+eval (Val x) = pure x eval (Add l r) = [| eval l + eval r |] eval (Random upper) = do val <- rndInt 0 upper                          putStrLn (show val)-                         return val+                         pure val  testExpr : Expr testExpr = Add (Add (Var "foo") (Val 42)) (Random 100)
test/effects002/test025.idr view
@@ -26,7 +26,7 @@                 Dst :- poke 4 (sub1 end) Oh                 res <- Dst :- peek 1 (S(S(S(S Z)))) Oh                 Dst :- free-                return (map (prim__zextB8_Int) res)+                pure (map (prim__zextB8_Int) res)  main : IO () main = ioe_run (runInit [Dst := (), Src := ()] testMemory)
+ test/error001/expected_ttquot view
@@ -0,0 +1,1 @@+test002.idr:5:Universe inconsistency
test/error002/test031.idr view
@@ -5,4 +5,4 @@ %language ErrorReflection  main : IO ()-main = return ()+main = pure ()
test/error003/ErrorReflection.idr view
@@ -47,7 +47,7 @@ reifyTy (P (DCon _ _) (NS (UN "TUnit") _) _) = Just TUnit reifyTy (App (App (P (DCon _ _) (NS (UN "TFun") _) _) t1) t2) = do ty1 <- reifyTy t1                                                                    ty2 <- reifyTy t2-                                                                   return $ TFun ty1 ty2+                                                                   pure $ TFun ty1 ty2 reifyTy (P _ (MN i n) _) = Just (TVar i n) reifyTy _ = Nothing 
test/error003/expected view
@@ -1,5 +1,4 @@-ErrorReflection.idr:68:5:-When checking right hand side of bad with expected type+ErrorReflection.idr:68:5:When checking right hand side of bad with expected type         Tm [] TUnit  DSL type error: (t(504) => t'(503)) doesn't match ()
test/error004/FunErrTest.idr view
@@ -22,10 +22,10 @@ total has2elts : Err -> Maybe (List ErrorReportPart) has2elts (CantSolveGoal tm _) = do lst <- extractList tm-                                   return [ TextPart "Could not prove that"-                                          , TermPart lst-                                          , TextPart "has at least two elements."-                                          ]+                                   pure [ TextPart "Could not prove that"+                                        , TermPart lst+                                        , TextPart "has at least two elements."+                                        ] has2elts e = Just [TextPart (show e)]  %error_handlers cadr cons1 has2elts
test/error005/expected view
@@ -1,34 +1,29 @@-error005.idr:13:1:-When checking right hand side of two with expected type+error005.idr:13:1:When checking right hand side of two with expected type         Fin 2  When checking argument prf to function Data.Fin.fromInteger:         When using 2 as a literal for a Fin 2                  2 is not strictly less than 2-error005.idr:16:1:-When checking right hand side of hahaha with expected type+error005.idr:16:1:When checking right hand side of hahaha with expected type         Fin n  When checking argument prf to function Data.Fin.fromInteger:         When using 0 as a literal for a Fin n                  0 is not strictly less than n-error005.idr:22:1:-When checking right hand side of notOk with expected type+error005.idr:22:1:When checking right hand side of notOk with expected type         Fin (plus 2 n)  When checking argument prf to function Data.Fin.fromInteger:         When using 2 as a literal for a Fin (S (S n))                  2 is not strictly less than S (S n)-error005.idr:23:24:-When checking right hand side of b0rken with expected type+error005.idr:23:24:When checking right hand side of b0rken with expected type         Fin 3  When checking argument prf to function Data.Fin.fromInteger:         When using n as a literal for a Fin 3                  Could not show that n is less than 3 because n is a bound                 variable instead of a constant Integer-error005.idr:28:1:-When checking right hand side of x with expected type+error005.idr:28:1:When checking right hand side of x with expected type         Fin 4  When checking argument prf to function Data.Fin.fromInteger:
+ test/error009/expected view
@@ -0,0 +1,1 @@+Uncaught error: Nothing found in namespace "Foo.Bar".
+ test/error009/run view
@@ -0,0 +1,2 @@+#!/usr/bin/env bash+${IDRIS:-idris} $@ -e "with Foo.Bar 42"
test/ffi002/test023.idr view
@@ -6,7 +6,7 @@  -- Provide the Unit type goodProvider : IO (Provider Type)-goodProvider = return (Provide (the Type ()))+goodProvider = pure (Provide (the Type ()))  %provide (Unit' : Type) with goodProvider @@ -15,7 +15,7 @@  -- Always fail badProvider : IO (Provider Type)-badProvider = return (Error "Always fails")+badProvider = pure (Error "Always fails")  %provide (t : Type) with badProvider 
test/ffi004/test026.idr view
@@ -11,8 +11,8 @@ -- If the file contains "Int", provide Int as a type, otherwise provide Nat fromFile : String -> IO (Provider Type) fromFile fname = do Right str <- readFile fname-                          | Left err => return (Provide Void)-                    return (Provide (strToType (trim str)))+                          | Left err => pure (Provide Void)+                    pure (Provide (strToType (trim str)))  %provide (T1 : Type) with fromFile "theType" %provide (T2 : Type) with fromFile "theOtherType"
test/ffi005/Postulate.idr view
@@ -3,7 +3,7 @@ %language TypeProviders  bad : IO (Provider Type)-bad = return $ pure Void+bad = pure $ pure Void  %provide postulate oops with bad 
test/ffi006/ffi006.idr view
@@ -11,7 +11,7 @@  show' : List Int -> IO String show' xs = do putStrLn "Ready to show..."-              return (show xs)+              pure (show xs)  testList : FFI_Export FFI_C "testHdr.h" [] testList = Data (List Int) "ListInt" $
test/ffi007/ffi007.idr view
@@ -55,4 +55,4 @@             i <- test7 fptr 3             printLn i             test8-            return ()+            pure ()
test/ffi008/ffi008.idr view
@@ -35,12 +35,12 @@ main = do     printLn $ sizeOf test1 == !size1     printLn $ sizeOf test2 == !size2-    fms <- return $ (test2#0) !mystruct+    fms <- pure $ (test2#0) !mystruct     poke I32 fms 122     print_mystruct     printLn $ fields test3     withAlloc test2 $ \p => do-        f1 <- return $ (test2 # 0) p+        f1 <- pure $ (test2 # 0) p         poke I32 f1 8         update I32 f1 (* 2)         print !(peek I32 f1)
+ test/ffi009/Bad.idr view
@@ -0,0 +1,36 @@+module Bad++%include c "ffi009.h"++private+get_allocation_size : Ptr -> IO Int+get_allocation_size = foreign FFI_C "get_allocation_size" (Ptr -> IO Int)++-- [ NOTE ]+--+-- As `commen_call` is a partial function and not inline, Idris should complain.++private+common_call : String -> Int -> IO ManagedPtr+common_call f l = do+  ptr <- foreign FFI_C+                 f+                 (Int -> IO Ptr)+                 l+  len <- get_allocation_size ptr+  pure (prim__registerPtr ptr len)++func_foo : IO ManagedPtr+func_foo = common_call "foo" 4++func_bar : IO ManagedPtr+func_bar = common_call "bar" 8+++namespace Main+  main : IO ()+  main = do+    foo <- func_foo+    bar <- func_bar++    printLn "I should not be seen."
+ test/ffi009/Good.idr view
@@ -0,0 +1,37 @@+module Good++%include c "ffi009.h"++private+get_allocation_size : Ptr -> IO Int+get_allocation_size = foreign FFI_C "get_allocation_size" (Ptr -> IO Int)++-- [ NOTE ]+--+-- As `commen_call` is a partial function and not inline, Idris should complain.++private+%inline+common_call : String -> Int -> IO ManagedPtr+common_call f l = do+  ptr <- foreign FFI_C+                 f+                 (Int -> IO Ptr)+                 l+  len <- get_allocation_size ptr+  pure (prim__registerPtr ptr len)++func_foo : IO ManagedPtr+func_foo = common_call "foo" 4++func_bar : IO ManagedPtr+func_bar = common_call "bar" 8+++namespace Main+  main : IO ()+  main = do+    foo <- func_foo+    bar <- func_bar++    printLn "I should be seen."
+ test/ffi009/expected view
@@ -0,0 +1,1 @@+"I should be seen."
+ test/ffi009/ffi009.c view
@@ -0,0 +1,44 @@+#include "ffi009.h"+++Vect* foo(int length)+{+  return new_empty_vect(length);+}++Vect* bar(int length)+{+  return new_empty_vect(length * 2);+}+++Vect* new_empty_vect(int l)+{+  unsigned char* vect;++  vect = malloc(sizeof(unsigned char) * l);++  if (vect == NULL){+    free(vect);+    return NULL;+  }++  Vect* v = malloc(sizeof(Vect));++  if (v==NULL){+    free(vect);+    free(v);+    return NULL;+  }++  v->value  = vect;+  v->length = l;++  return v;+}+++int get_allocation_size(Vect* v)+{+  return sizeof(Vect) + v->length;+}
+ test/ffi009/ffi009.h view
@@ -0,0 +1,20 @@+#ifndef FFI009_H+#define FFI009_H++#include <idris_rts.h>+++typedef struct+{+  unsigned char* value;+  int length;+} Vect;++int get_allocation_size(Vect* v);++Vect* new_empty_vect(int length);++Vect* foo(int length);+Vect* bar(int length);++#endif /* FFI009_H */
+ test/ffi009/run view
@@ -0,0 +1,5 @@+#!/usr/bin/env bash+${IDRIS:-idris} $@ Bad.idr -o bad --cg-opt "ffi009.c" --cg-opt "-fno-strict-overflow"+${IDRIS:-idris} $@ Good.idr -o good --cg-opt "ffi009.c"+./good+rm -f *.ibc good
+ test/idrisdoc004/TestInterfaces.idr view
@@ -0,0 +1,9 @@+module TestInterfaces++||| This is a test+|||+||| @ a Test arg+public export+interface Test a where+  ||| Test function+  test : a -> Int
− test/idrisdoc004/TestTypeclasses.idr
@@ -1,9 +0,0 @@-module TestTypeclasses--||| This is a test-|||-||| @ a Test arg-public export-interface Test a where-  ||| Test function-  test : a -> Int
test/idrisdoc004/expected view
@@ -1,1 +1,1 @@-Typeclasses are documented+Interfaces are documented
test/idrisdoc004/run view
@@ -1,5 +1,5 @@ #!/usr/bin/env bash-# Tests that documentation is generated for typeclasses-${IDRIS:-idris} $@ --mkdoc test_typeclasses.ipkg-[ -d test_typeclasses_doc ] && echo "Typeclasses are documented"+# Tests that documentation is generated for interfaces+${IDRIS:-idris} $@ --mkdoc test_interfaces.ipkg+[ -d test_interfaces_doc ] && echo "Interfaces are documented" rm -rf *.ibc *_doc
+ test/idrisdoc004/test_interfaces.ipkg view
@@ -0,0 +1,6 @@+package test_interfaces++opts = "--quiet"++modules = TestInterfaces+
− test/idrisdoc004/test_typeclasses.ipkg
@@ -1,6 +0,0 @@-package test_typeclasses--opts = "--quiet"--modules = TestTypeclasses-
test/interactive007/run view
@@ -1,2 +1,2 @@ #!/usr/bin/env bash-${IDRIS:-idris} $@ -p contrib --nobanner --nocolor < input+${IDRIS:-idris} $@ -p contrib --nobanner --nocolor < input | perl -pe 's-Data\\Z-Data/Z-g'
test/interactive010/expected view
@@ -4,9 +4,9 @@ Usage is :doc <functionname> Usage is :wc <functionname> Usage is :printdef <functionname>-pat {ty504} : Type toplevel.u. pat {__class505} : Prelude.Interfaces.Fractional {ty504}. Prelude.Interfaces./ {ty504} {__class505}+pat {ty504} : Type toplevel.u. pat {__interface505} : Prelude.Interfaces.Fractional {ty504}. Prelude.Interfaces./ {ty504} {__interface505} - : pty {ty504} : Type toplevel.u. pty {__class505} : Prelude.Interfaces.Fractional {ty504}. {ty504} -> {ty504} -> {ty504}+ : pty {ty504} : Type toplevel.u. pty {__interface505} : Prelude.Interfaces.Fractional {ty504}. {ty504} -> {ty504} -> {ty504} (input):1:1: error: expected: ":",     dependent type signature,     end of input
− test/interfaces001/ClassName.idr
@@ -1,49 +0,0 @@-module ClassName--||| A fancy shower with a constructor-||| @ a the thing to be shown-interface MyShow a where-  ||| Build a MyShow-  constructor MkMyShow-  ||| The shower-  ||| @ x will become a string-  myShow : (x : a) -> String--twiceAString : MyShow a => a -> String-twiceAString x = myShow x ++ myShow x--implementation MyShow Integer where-  myShow x = show x--badShow : MyShow Integer-badShow = MkMyShow (const "hej")--test1 : twiceAString 2 = "22"-test1 = Refl--test2 : twiceAString @{ClassName.badShow} 2 = "hejhej"-test2 = Refl---||| Parent interface fun-interface MyMagma a where-  constructor MkMyMagma-  total op : a -> a -> a--||| Semigroup-interface MyMagma a => MySemigroup a where-  constructor MkMySemigroup-  total isAssoc : (x, y, z : a) -> op x $ op y z = op (op x y) z--implementation [addition] MyMagma Nat where-  op = plus--additionS : MySemigroup Nat-additionS = MkMySemigroup @{addition} plusAssociative--doIt : MySemigroup a => a -> List a -> a-doIt x [] = x-doIt x (y :: xs) = doIt (x `op` y) xs--test : Nat-test = doIt @{additionS} 22 [1,2,3,4]
+ test/interfaces001/InterfaceName.idr view
@@ -0,0 +1,49 @@+module InterfaceName++||| A fancy shower with a constructor+||| @ a the thing to be shown+interface MyShow a where+  ||| Build a MyShow+  constructor MkMyShow+  ||| The shower+  ||| @ x will become a string+  myShow : (x : a) -> String++twiceAString : MyShow a => a -> String+twiceAString x = myShow x ++ myShow x++implementation MyShow Integer where+  myShow x = show x++badShow : MyShow Integer+badShow = MkMyShow (const "hej")++test1 : twiceAString 2 = "22"+test1 = Refl++test2 : twiceAString @{InterfaceName.badShow} 2 = "hejhej"+test2 = Refl+++||| Parent interface fun+interface MyMagma a where+  constructor MkMyMagma+  total op : a -> a -> a++||| Semigroup+interface MyMagma a => MySemigroup a where+  constructor MkMySemigroup+  total isAssoc : (x, y, z : a) -> op x $ op y z = op (op x y) z++implementation [addition] MyMagma Nat where+  op = plus++additionS : MySemigroup Nat+additionS = MkMySemigroup @{addition} plusAssociative++doIt : MySemigroup a => a -> List a -> a+doIt x [] = x+doIt x (y :: xs) = doIt (x `op` y) xs++test : Nat+test = doIt @{additionS} 22 [1,2,3,4]
test/interfaces001/run view
@@ -1,3 +1,3 @@ #!/usr/bin/env bash-${IDRIS:-idris} $@ --quiet --nocolour --consolewidth 70 ClassName.idr < input+${IDRIS:-idris} $@ --quiet --nocolour --consolewidth 70 InterfaceName.idr < input rm -f *.ibc
test/interfaces005/expected view
@@ -2,6 +2,6 @@ Set.TreeSet.Set must be defined by a type or data constructor No such variable TreeSet interfaces005b.idr:4:11:-Data definitions not allowed in a class declaration+Data definitions not allowed in an interface declaration interfaces005b.idr:18:3:SetSig is not an interface No such variable TreeSet
test/interfaces006/interfaces006.idr view
@@ -10,7 +10,7 @@  infixr 1 =<< interface Functor c m => Monad (c: k -> k -> Type) (m: k -> k) where-  return: c x (m x)+  pure: c x (m x)   join: c (m (m x)) (m x)   (=<<) : c x (m y) -> c (m x) (m y) 
test/io001/test004.idr view
@@ -5,13 +5,13 @@                 case v of                      True => do b                                 mwhile t b-                     False => return ()+                     False => pure ()  dumpFile : String -> IO () dumpFile fn = do { Right h <- openFile fn Read                    mwhile (do { -- putStrLn "TEST"                                 x <- fEOF h-                                return (not x) })+                                pure (not x) })                           (do { Right l <- fGetLine h                                 putStr l })                    closeFile h }
test/io002/test008.idr view
@@ -14,7 +14,7 @@   ioVals : IO (String, String)-ioVals = do { return ("First", "second") }+ioVals = do { pure ("First", "second") }  main : IO () main = do (a, b) <- ioVals
test/io003/test018.idr view
@@ -11,11 +11,12 @@           putStrLn x           putStrLn "Received"           sendToThread sender 0 "Hello to you too!"-          return ()+          pure ()  ping : Ptr -> IO ()-ping thread = do sendToThread thread 0 (prim__vm, "Hello!")-                 return ()+ping thread = do me <- getMyVM+                 sendToThread thread 0 (me, "Hello!")+                 pure ()  pingpong : IO () pingpong
test/io003/test018a.idr view
@@ -11,24 +11,24 @@         msg <- recv         Lift (putStrLn ("Reply: " ++ show msg))         send main "Done"-        return ()+        pure ()  pong : Process String () pong = do -- Lift (putStrLn "Waiting for message")           (sender, m) <- recvWithSender           Lift $ putStrLn ("Received " ++ m)           send sender ("Hello back!")-          return ()+          pure ()  mainProc : Process String () mainProc = do mainID <- myID               pongth <- create pong               pingth <- create (ping mainID pongth)               recv -- block until everything done-              return ()+              pure ()  repeatIO : Int -> IO ()-repeatIO 0 = return ()+repeatIO 0 = pure () repeatIO n = do printLn n                 run mainProc                 repeatIO (n - 1)
test/layout001/expected view
@@ -1,84 +1,68 @@-Checking layout001a.idr ./layout001a.idr:5:1: error: Wrong     indention: should be greater     than context     indentation, expected: space y  ^ -Checking layout001b.idr ./layout001b.idr:5:3: error: Wrong     indention: should be greater     than context     indentation, expected: space = y    ^ -Checking layout001c.idr ./layout001c.idr:3:1: error: Wrong     indention: should be greater     than context     indentation, expected: space 2  ^ -Checking layout001d.idr-Checking layout001e.idr ./layout001e.idr:6:1: error: Wrong     indention: should be greater     than context     indentation, expected: space 3  ^ -Checking layout001f.idr ./layout001f.idr:6:2: error: Wrong     indention: should be greater     than context     indentation, expected: space  3   ^ -Checking layout001g.idr ./layout001g.idr:6:3: error: Wrong     indention: should be greater     than context     indentation, expected: space   3    ^ -Checking layout001h.idr ./layout001h.idr:6:3: error: Wrong     indention: should be greater     than context     indentation, expected: space   3    ^ -Checking layout001i.idr ./layout001i.idr:6:4: error: Wrong     indention: should be greater     than context     indentation, expected: space    3     ^ -Checking layout001j.idr ./layout001j.idr:6:5: error: Wrong     indention: should be greater     than context     indentation, expected: space     3      ^ -Checking layout001k.idr-Checking layout001l.idr ./layout001l.idr:6:1: error: Wrong     indention: should be greater     than context     indentation, expected: space y  ^ -Checking layout001n.idr-Checking mplus1.idr-mplus1.idr:13:31:-When checking right hand side of term with expected type+mplus1.idr:13:31:When checking right hand side of term with expected type         Maybe Int  When checking an application of function Prelude.Applicative.pure:         No such variable f-Checking mplus2.idr ./mplus2.idr:17:37: error: not     end of block, expected: ")",     "->", ";", "in",@@ -89,5 +73,4 @@     end of input                                     `mplus` pure f                                      ^              -Checking mplus3.idr mplus3.idr:11:1:warning - Unreachable case: term
test/layout001/run view
@@ -1,8 +1,22 @@ #!/usr/bin/env bash -for file in *.idr; do-  echo Checking ${file}-  ${IDRIS:-idris} --check $@ ${file}-done+${IDRIS:-idris} --nobanner --nocolour --quiet <<!+:load layout001a.idr+:load layout001b.idr+:load layout001c.idr+:load layout001d.idr+:load layout001e.idr+:load layout001f.idr+:load layout001g.idr+:load layout001h.idr+:load layout001i.idr+:load layout001j.idr+:load layout001k.idr+:load layout001l.idr+:load layout001n.idr+:load mplus1.idr+:load mplus2.idr+:load mplus3.idr+!  rm -f *.ibc
test/meta001/Finite.idr view
@@ -23,9 +23,9 @@  mkFin : Nat -> Nat -> Elab Raw mkFin Z j = fail [TermPart `(Fin Z), TextPart "is uninhabitable!"]-mkFin (S k) Z = return `(FZ {k=~(quote k)})+mkFin (S k) Z = pure `(FZ {k=~(quote k)}) mkFin (S k) (S j) = do i <- mkFin k j-                       return `(FS {k=~(quote k)} ~i)+                       pure `(FS {k=~(quote k)} ~i)  mkToClause : TTName -> (size, i : Nat) ->              (constr : (TTName, List CtorArg, Raw)) ->@@ -40,14 +40,14 @@                (constr : (TTName, List CtorArg, Raw)) ->                Elab (FunClause Raw) mkFromClause fn size i (n, [], Var ty) =-  return $ MkFunClause (RApp (Var fn) !(mkFin size i)) (Var n)+  pure $ MkFunClause (RApp (Var fn) !(mkFin size i)) (Var n) mkFromClause fn size i (n, _, ty) =   fail [TextPart "unsupported constructor", NamePart n]   mkOk1Clause : TTName -> (size, i : Nat) -> (constr : (TTName, List CtorArg, Raw)) -> Elab (FunClause Raw) mkOk1Clause fn size i (n, [], Var ty) =-  return $ MkFunClause (RApp (Var fn) (Var n))+  pure $ MkFunClause (RApp (Var fn) (Var n))                        [| (Var (UN "Refl")) (Var ty) (Var n) |] mkOk1Clause fn size i (n, _, ty) =   fail [TextPart "unsupported constructor", NamePart n]@@ -55,7 +55,7 @@  mkOk2Clause : TTName -> (size, i : Nat) -> (constr : (TTName, List CtorArg, Raw)) -> Elab (FunClause Raw) mkOk2Clause fn size i (n, [], Var ty) =-  return $ MkFunClause (RApp (Var fn) !(mkFin size i))+  pure $ MkFunClause (RApp (Var fn) !(mkFin size i))                        [| (Var `{Refl}) `(Fin ~(quote size))                                         !(mkFin size i) |] mkOk2Clause fn size i (n, _, ty) =@@ -65,10 +65,10 @@ mkToClauses : TTName -> Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw)) mkToClauses fn size xs = mkToClauses' Z xs   where mkToClauses' : Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw))-        mkToClauses' k []        = return []+        mkToClauses' k []        = pure []         mkToClauses' k (x :: xs) = do rest <- mkToClauses' (S k) xs                                       clause <- mkToClause fn size k x-                                      return $ clause :: rest+                                      pure $ clause :: rest  ||| Generate a clause for the end of a pattern-match on Fins that ||| declares its own impossibility.@@ -84,11 +84,11 @@                      (RApp (Var fn) lhsArg)      let rhs = RBind pv (PVar `(Fin Z : Type))                      `(FinZElim {a=~(goal lhsArg)} ~(Var pv))-     return $ MkFunClause lhs rhs+     pure $ MkFunClause lhs rhs   where lhsBody : TTName -> Nat -> Elab Raw-        lhsBody f Z = return $ Var f+        lhsBody f Z = pure $ Var f         lhsBody f (S k) = do smaller <- lhsBody f k-                             return `(FS {k=~(quote k)} ~smaller)+                             pure `(FS {k=~(quote k)} ~smaller)   mkFromClauses : TTName -> TTName -> Nat ->@@ -96,26 +96,26 @@ mkFromClauses fn ty size xs = mkFromClauses' Z xs   where mkFromClauses' : Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw))         mkFromClauses' k []        =-             return [!(mkAbsurdFinClause fn (const (Var ty)) size)]+             pure [!(mkAbsurdFinClause fn (const (Var ty)) size)]         mkFromClauses' k (x :: xs) = do rest <- mkFromClauses' (S k) xs                                         clause <- mkFromClause fn size k x-                                        return $ clause :: rest+                                        pure $ clause :: rest  mkOk1Clauses : TTName -> Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw)) mkOk1Clauses fn size xs = mkOk1Clauses' Z xs   where mkOk1Clauses' : Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw))-        mkOk1Clauses' k []        = return []+        mkOk1Clauses' k []        = pure []         mkOk1Clauses' k (x :: xs) = do rest <- mkOk1Clauses' (S k) xs                                        clause <- mkOk1Clause fn size k x-                                       return $ clause :: rest+                                       pure $ clause :: rest  mkOk2Clauses : TTName -> Nat -> List (TTName, List CtorArg, Raw) -> (Raw -> Raw) -> Elab (List (FunClause Raw)) mkOk2Clauses fn size xs resTy = mkOk2Clauses' Z xs   where mkOk2Clauses' : Nat -> List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw))-        mkOk2Clauses' k []        = return [!(mkAbsurdFinClause fn resTy size)]+        mkOk2Clauses' k []        = pure [!(mkAbsurdFinClause fn resTy size)]         mkOk2Clauses' k (x :: xs) = do rest <- mkOk2Clauses' (S k) xs                                        clause <- mkOk2Clause fn size k x-                                       return $ clause :: rest+                                       pure $ clause :: rest   genToFin : (to, from, ok1, ok2, ty : TTName) -> Elab ()@@ -153,7 +153,7 @@      ok2Clauses <- mkOk2Clauses ok2 size constrs ok2ResTy      defineFunction $ DefineFun ok2 ok2Clauses -     return ()+     pure ()   deriveFinite : Elab ()
test/meta002/AgdaStyleReflection.idr view
@@ -1,5 +1,5 @@ ||| Implement an Agda-style reflection system as a DSL inside of-||| Idris's reflected elaboration. Requires handling type class+||| Idris's reflected elaboration. Requires handling interface ||| resolution and implicit arguments - some of the same features as ||| the Idris elaborator itself. |||@@ -73,10 +73,10 @@ quoteTerm' : List TTName -> Raw -> Elab Term quoteTerm' env (Var n) =     case findIndex (==n) env of-      Just i => return (Var i [])+      Just i => pure (Var i [])       Nothing =>         case findIndex (\(n', _) => n == n') !getEnv of-          Just i => return (Var i [])+          Just i => pure (Var i [])           Nothing => do [(n', nt, ty)] <- lookupTy n                           | [] => fail [TextPart "No such variable", NamePart n]                           | vs => fail ([TextPart "Can't disambiguate"] ++@@ -136,7 +136,7 @@    where getVar : Nat -> List TTName -> Elab TTName         getVar _     []         = fail [TextPart "Variable out of scope"]-        getVar Z     (n :: _  ) = return n -- NB assumes unique names!+        getVar Z     (n :: _  ) = pure n -- NB assumes unique names!         getVar (S k) (_ :: env) = getVar k env  ||| Prepare to apply a global by matching its argument plicities to
test/meta002/Tacs.idr view
@@ -26,7 +26,7 @@ intros = do g <- getGoal             case snd g of               `(~_ -> ~_) => intro'-              _ => return ()+              _ => pure ()  foo : Nat -> Nat foo = %runElab (do intro (UN "fnord")@@ -36,7 +36,7 @@  %runElab (do n <- isTCName `{Nat}              s <- isTCName `{Show}-             if n || not s then fail [TextPart "nope"] else return ())+             if n || not s then fail [TextPart "nope"] else pure ())  -- Note that <|> is equivalent to "try" in the old tactics. -- In these tactics, we use ordinary do notation and ordinary documentation strings!@@ -121,7 +121,7 @@           mkTypeHole hint = do holeName <- gensym hint                                claim holeName RType                                unfocus holeName-                               return holeName+                               pure holeName    -- FIXME: Removing the let-bound Elab script showed a deficiency in   -- how accessible arguments are identified in type signatures. It@@ -217,13 +217,13 @@               mkEnvH = do envH <- gensym "env"                           claim envH `(List Ty)                           unfocus envH-                          return envH+                          pure envH                mkTyH : Elab TTName               mkTyH = do tyH <- gensym "ty"                          claim tyH `(Ty)                          unfocus tyH-                         return tyH+                         pure tyH                mkIx : Fin n -> Elab ()               mkIx FZ = do envH <- mkEnvH
+ test/mktest.pl view
@@ -0,0 +1,21 @@+#!/usr/bin/env perl++if ($#ARGV>=0) {+    $test=shift(@ARGV);+} else {+    print "What's its name?\n";+    exit;+}++mkdir($test);++chdir($test);+open(FOO,">run");++print FOO "#!/usr/bin/env bash\n";+print FOO "\${IDRIS:-idris} \$@ $test.idr -o $test\n";+print FOO "./$test\n";print FOO "rm -f $test *.ibc\n";++close(FOO);++system("chmod +x run");
+ test/pkg007/expected view
@@ -0,0 +1,1 @@+(True, "VROOOOM", Pedal) : (Bool, String, CarPart)
+ test/pkg007/input view
@@ -0,0 +1,4 @@+:module Toy+:module Toy.Vehicle+:module Toy.Vehicle.Car+(toysAreGreat, carNoise, Pedal)
+ test/pkg007/run view
@@ -0,0 +1,7 @@+#!/usr/bin/env bash+cd toy+${IDRIS:-idris} $@ --build toy.ipkg --ibcsubdir ../ibcout+cd ../ibcout+${IDRIS:-idris} $@ --quiet < ../input+cd ..+rm -rf ibcout
+ test/pkg007/toy/Toy.idr view
@@ -0,0 +1,4 @@+module Toy++toysAreGreat : Bool+toysAreGreat = True
+ test/pkg007/toy/Toy/Vehicle.idr view
@@ -0,0 +1,4 @@+module Toy.Vehicle++carNoise : String+carNoise = "VROOOOM"
+ test/pkg007/toy/Toy/Vehicle/Car.idr view
@@ -0,0 +1,3 @@+module Toy.Vehicle.Car++data CarPart = Wheel | Pedal | Window
+ test/pkg007/toy/toy.ipkg view
@@ -0,0 +1,7 @@+package toy++modules = Toy,+          Toy.Vehicle,+          Toy.Vehicle.Car++opts = "--quiet"
test/prelude001/prelude001.idr view
@@ -3,15 +3,12 @@ main : IO () main = do   printLn $ lines "" == []-  -- `lines` seems to ignore too many trailing newlines.-  printLn $ lines "\n" == [] -- FIXME: Should be [""].-  printLn $ lines "\n\n" == [] -- FIXME: Should be ["", ""].-  printLn $ lines "\n\n\n" == [] -- FIXME: Should be ["", "", ""].+  printLn $ lines "\n" == [""]+  printLn $ lines "\n\n" == ["", ""]+  printLn $ lines "\n\n\n" == ["", "", ""]   printLn $ lines "1\n2\n3" == ["1", "2", "3"]   printLn $ lines "1\n2\n3\n" == ["1", "2", "3"]   printLn $ unlines [] == ""-  -- `unlines` works as advertised doesn't follow Haskell here.-  -- When files are written using unlines, vim complains of "noeoln".-  printLn $ unlines ["1"] == "1" -- FIXME: Should be "1\n"-  printLn $ unlines ["1", "2"] == "1\n2" -- FIXME: Should be "1\n2\n"-  printLn $ unlines ["1", "2", "3"] == "1\n2\n3" -- FIXME: Should be "1\n2\n3\n"+  printLn $ unlines ["1"] == "1\n"+  printLn $ unlines ["1", "2"] == "1\n2\n"+  printLn $ unlines ["1", "2", "3"] == "1\n2\n3\n"
+ test/primitives004-disabled/expected view
@@ -0,0 +1,4 @@+<3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3>+<3, 3, 3, 3, 3, 3, 3, 3>+<3, 3, 3, 3>+<3, 3>
+ test/primitives004-disabled/primitives004.idr view
@@ -0,0 +1,8 @@+module Main++main : IO ()+main = do+  putStrLn . show $ uniformB8x16 3+  putStrLn . show $ uniformB16x8 3+  putStrLn . show $ uniformB32x4 3+  putStrLn . show $ uniformB64x2 3
+ test/primitives004-disabled/run view
@@ -0,0 +1,4 @@+#!/usr/bin/env bash+${IDRIS:-idris} $@ -o primitives004 primitives004.idr --nocolour+./primitives004+rm -f primitives004 *.ibc
test/primitives006/Data/ByteArray.idr view
@@ -31,7 +31,7 @@ allocate : Int -> IO ByteArray allocate sz = do   ptr <- foreign FFI_C "array_alloc" (Int -> IO CData) sz-  return $ BA ptr sz+  pure $ BA ptr sz  export reallocate : Int -> ByteArray -> IO ()@@ -42,42 +42,42 @@ peek : Int -> ByteArray -> IO Byte peek ofs (BA ptr sz)   = if (ofs < 0 || ofs >= sz)-      then return 0+      then pure 0       else foreign FFI_C "array_peek" (Int -> CData -> IO Byte) ofs ptr  export peekInt : Int -> ByteArray -> IO Int peekInt ofs (BA ptr sz)   = if (ofs < 0 || ofs+bytesPerInt > sz)-      then return 0+      then pure 0       else foreign FFI_C "array_peek_int" (Int -> CData -> IO Int) ofs ptr  export poke : Int -> Byte -> ByteArray -> IO () poke ofs b (BA ptr sz)   = if (ofs < 0 || ofs >= sz)-      then return ()+      then pure ()       else foreign FFI_C "array_poke" (Int -> Byte -> CData -> IO ()) ofs b ptr  export pokeInt : Int -> Int -> ByteArray -> IO () pokeInt ofs i (BA ptr sz)   = if (ofs < 0 || ofs+bytesPerInt > sz)-      then return ()+      then pure ()       else foreign FFI_C "array_poke_int" (Int -> Int -> CData -> IO ()) ofs i ptr  export copy : (ByteArray, Int) -> (ByteArray, Int) -> Int -> IO () copy (BA srcPtr srcSz, srcIx) (BA dstPtr dstSz, dstIx) count   = if (srcIx < 0 || dstIx < 0 || (srcIx+count) > srcSz || (dstIx+count) > dstSz)-      then return ()+      then pure ()       else foreign FFI_C "array_copy" (CData -> Int -> CData -> Int -> Int -> IO ()) srcPtr srcIx dstPtr dstIx count  export fill : Int -> Int -> Byte -> ByteArray -> IO () fill ofs count b (BA ptr sz)   = if (ofs < 0 || ofs+count > sz)-      then return ()+      then pure ()       else foreign FFI_C "array_fill" (Int -> Int -> Byte -> CData -> IO ()) ofs count b ptr  export@@ -88,7 +88,7 @@ compare : (ByteArray, Int) -> (ByteArray, Int) -> Int -> IO Int compare (BA ptrL szL, ofsL) (BA ptrR szR, ofsR) count   = if (ofsL < 0 || ofsL+count > szL || ofsR < 0 || ofsR+count > szR)-      then return 0+      then pure 0       else foreign FFI_C "array_compare" (CData -> Int -> CData -> Int -> Int -> IO Int) ptrL ofsL ptrR ofsR count  export@@ -96,5 +96,5 @@ find b (BA ptr sz) ofs end = do   ofs <- foreign FFI_C "array_find" (Byte -> CData -> Int -> Int -> IO Int) b ptr ofs end   if ofs < 0-    then return $ Nothing-    else return $ Just ofs+    then pure $ Nothing+    else pure $ Just ofs
test/primitives006/Data/Bytes.idr view
@@ -30,7 +30,7 @@   arr <- BA.allocate (BA.bytesPerInt + capacity)   BA.pokeInt 0 dataOfs arr   BA.fill dataOfs capacity 0 arr  -- zero the array-  return $ B arr dataOfs dataOfs+  pure $ B arr dataOfs dataOfs  export length : Bytes -> Int@@ -59,7 +59,7 @@           else BA.size arr - ofs   B arr' ofs' end' <- allocate $ (factor*bytesAvailable) `max` minimalCapacity   BA.copy (arr, ofs) (arr', ofs') bytesUsed-  return $ B arr' ofs' (ofs' + bytesUsed)+  pure $ B arr' ofs' (ofs' + bytesUsed)  export snoc : Bytes -> Byte -> Bytes@@ -68,17 +68,17 @@        if end >= BA.size arr         then unsafePerformIO $ do  -- need more space           grown <- grow 2 bs-          return $ snoc grown byte+          pure $ snoc grown byte         else unsafePerformIO $ do           maxUsed <- BA.peekInt 0 arr           if maxUsed > end             then do  -- someone already took the headroom, need copying               copy <- grow 2 bs-              return $ snoc copy byte+              pure $ snoc copy byte             else do  -- can mutate               BA.pokeInt 0 (end+1) arr               BA.poke end byte arr-              return $ B arr ofs (end+1)+              pure $ B arr ofs (end+1)  infixl 7 |> export@@ -97,7 +97,7 @@       then SnocView.Nil       else unsafePerformIO $ do         last <- BA.peek (end-1) arr-        return $ SnocView.Snoc (B arr ofs (end-1)) last+        pure $ SnocView.Snoc (B arr ofs (end-1)) last  namespace ConsView   data ConsView : Type where@@ -111,7 +111,7 @@       then ConsView.Nil       else unsafePerformIO $ do         first <- BA.peek ofs arr-        return $ ConsView.Cons first (B arr (ofs+1) end)+        pure $ ConsView.Cons first (B arr (ofs+1) end)  infixr 7 ++ export@@ -121,17 +121,17 @@       if endL + countR > BA.size arrL         then unsafePerformIO $ do  -- need more space           grown <- grow 2 bsL-          return $ grown ++ bsR+          pure $ grown ++ bsR         else unsafePerformIO $ do           maxUsedL <- BA.peekInt 0 arrL           if maxUsedL > endL             then do  -- headroom taken               copyL <- grow 2 bsL-              return $ copyL ++ bsR+              pure $ copyL ++ bsR             else do  -- can mutate               BA.pokeInt 0 (endL + countR) arrL               BA.copy (arrR, ofsR) (arrL, endL) countR-              return $ B arrL ofsL (endL + countR)+              pure $ B arrL ofsL (endL + countR)  export dropPrefix : Int -> Bytes -> Bytes@@ -245,7 +245,7 @@     let countR = endR - ofsR     let commonCount = countL `min` countR     result <- BA.compare (arrL, ofsL) (arrR, ofsR) commonCount-    return $+    pure $       if result /= 0         then i2o result         else compare countL countR
test/primitives006/load-test.idr view
@@ -26,7 +26,7 @@         in printLn $ (show b ++ "/" ++ show n, length expanded, length elines)  alloc : Int -> Int -> IO Int-alloc x 0 = return x+alloc x 0 = pure x alloc x i = do   -- allocate an array   arr <- BA.allocate (64 * 1024 * 1024)
test/proof003/test015.idr view
@@ -68,7 +68,7 @@ readNum = do putStr "Enter a number:"              i <- getLine              let n : Integer = cast i-             return (fromInteger n)+             pure (fromInteger n)  main : IO () main = do let Just bin1 = natToBin 8 42
test/proof010/proof010.idr view
@@ -1,24 +1,24 @@ data MyShow : Type -> Type where-     ShowInstance : (show : a -> String) -> MyShow a+     ShowImplementation : (show : a -> String) -> MyShow a  myshow : {auto inst : MyShow a} -> a -> String-myshow {inst = ShowInstance show} x1 = show x1 +myshow {inst = ShowImplementation show} x1 = show x1  %hint showNat : MyShow Nat-showNat = ShowInstance show +showNat = ShowImplementation show  %hint showFn : MyShow (a -> b)-showFn = ShowInstance (\x => "<< function >>")+showFn = ShowImplementation (\x => "<< function >>")  %hint showBools : MyShow (Bool, Bool)-showBools = ShowInstance (\x => "some bools")+showBools = ShowImplementation (\x => "some bools")  %hint showStuff : MyShow a -> MyShow b -> MyShow (a, b)-showStuff sa sb = ShowInstance showPair+showStuff sa sb = ShowImplementation showPair   where     showPair : (a, b) -> String     showPair (x, y) = myshow x ++ ", " ++ myshow y
test/proof011/expected view
@@ -1,14 +1,18 @@-proof011.idr:19:9:-When checking right hand side of vassoc' with expected type+proof011.idr:19:9:When checking right hand side of vassoc' with expected type         (x :: xs) ++ ys ++ zs = ((x :: xs) ++ ys) ++ zs -rewriting xs ++ ys ++ xs to (xs ++ ys) ++-                            xs did not change type x :: xs ++ ys ++ zs =-                                                   x :: (xs ++ ys) ++ zs-proof011a.idr:13:9:-When checking right hand side of vassoc' with expected type+rewriting xs ++ ys ++ xs to (xs ++ ys) ++ xs did not change type x ::+                                                                 xs +++                                                                 ys ++ zs =+                                                                 x ::+                                                                 (xs ++ ys) +++                                                                 zs+proof011a.idr:13:9:When checking right hand side of vassoc' with expected type         (x :: xs) ++ ys ++ zs = ((x :: xs) ++ ys) ++ zs -rewriting xs ++ ys ++ xs to (xs ++ ys) ++-                            xs did not change type x :: xs ++ ys ++ zs =-                                                   x :: (xs ++ ys) ++ zs+rewriting xs ++ ys ++ xs to (xs ++ ys) ++ xs did not change type x ::+                                                                 xs +++                                                                 ys ++ zs =+                                                                 x ::+                                                                 (xs ++ ys) +++                                                                 zs
test/proofsearch002/Process.idr view
@@ -347,7 +347,7 @@ getRequest :  EvalState iface hs -> Maybe (Ptr, (ty ** (Nat, iface ty)), EvalState iface hs) getRequest (MkEvalState queue reply clients nh)       = do (pid, req, queue') <- removeReq [] queue-          return (pid, req, MkEvalState queue' reply clients nh)+          pure (pid, req, MkEvalState queue' reply clients nh)  countClients : EvalState iface hs -> (Nat, EvalState iface hs) countClients (MkEvalState queue reply clients nh) @@ -378,7 +378,8 @@              k (MkPID ptr) st   eval st (Work proc cont) k -        = do ptr <- fork (eval (MkEvalState [] [] 0 0) (proc (MkPID prim__vm))+        = do me <- getMyVM+             ptr <- fork (eval (MkEvalState [] [] 0 0) (proc (MkPID me))                                (\_, _ => pure ()))              eval (record { clients = clients st + 1 } st) cont k @@ -420,11 +421,12 @@                        k val st''')  eval {hs} st (Connect {serveri} (MkPID pid)) k -     = if pid == prim__vm then k False st else do-          v <- sendToThread pid 0 (MsgQuery {iface=serveri} {hs}-                                            ConnectMsg)-          -- TODO: Wait for ACK-          k (v == 1) st+     = do me <- getMyVM+          if pid == me then k False st else do+            v <- sendToThread pid 0 (MsgQuery {iface=serveri} {hs}+                                              ConnectMsg)+            -- TODO: Wait for ACK+            k (v == 1) st  eval {hs} st (Disconnect {serveri} (MkPID pid)) k       = do v <- sendToThread pid 0 (MsgQuery {iface=serveri} {hs} 
test/quasiquote001/QuasiquoteBasics.idr view
@@ -18,9 +18,6 @@ thing : TT -> TT thing tm = `(with List [Type, ~tm]) --- namespace Main   main : IO ()   main = do putStrLn . show $ twoElems
test/quasiquote003/expected view
@@ -1,5 +1,4 @@-NoInfer.idr:11:5:-When checking right hand side of zzz with expected type+NoInfer.idr:11:5:When checking right hand side of zzz with expected type         TT  No such variable k
− test/reg003/expected
@@ -1,6 +0,0 @@-reg003a.idr:4:11:When checking type of Main.ECons:-No such variable OddList-reg003a.idr:7:11:When checking type of Main.OCons:-No such variable EvenList-reg003a.idr:9:6:When checking type of Main.test:-No such variable EvenList
− test/reg003/reg003.idr
@@ -1,13 +0,0 @@--mutual-  namespace Even-    data EvenList : Type where-        Nil  : EvenList-        (::) : Nat -> OddList -> EvenList--  namespace Odd-    data OddList : Type where-        (::) : Nat -> EvenList -> OddList--test : EvenList-test = [1, 2, 3, 4, 5, 6]
− test/reg003/reg003a.idr
@@ -1,10 +0,0 @@--data EvenList : Type where-    ENil  : EvenList-    ECons : Nat -> OddList -> EvenList--data OddList : Type where-    OCons : Nat -> EvenList -> OddList--test : EvenList-test = ECons 1 ENil
− test/reg003/run
@@ -1,4 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --check reg003.idr-${IDRIS:-idris} $@ --check reg003a.idr-rm -f *.ibc
− test/reg006/expected
@@ -1,2 +0,0 @@-reg006.idr:17:1:-RBTree.lookup is possibly not total due to recursive path RBTree.lookup --> RBTree.lookup
− test/reg006/reg006.idr
@@ -1,28 +0,0 @@-module RBTree--data Colour = Red | Black--data RBTree : Type -> Type -> Nat -> Colour -> Type where-  Leaf : RBTree k v Z Black-  RedBranch : k -> v -> RBTree k v n Black -> RBTree k v n Black -> RBTree k v n Red-  BlackBranch : k -> v -> RBTree k v n x -> RBTree k v n y -> RBTree k v (S n) Black--toBlack : RBTree k v n c -> (m ** (RBTree k v m Black, Either (m = n) (m = (S n))))-toBlack (RedBranch k v l r) = (_ ** (BlackBranch k v l r, Right Refl))-toBlack Leaf = (_ ** (Leaf, Left Refl))-toBlack (BlackBranch k v l r) = (_ ** (BlackBranch k v l r, Left Refl))--total -- Yes, but the checker can't spot it-lookup : Ord k => k -> RBTree k v n Black -> Maybe v-lookup k Leaf = Nothing-lookup k (BlackBranch k0 v0 l r) =-  case compare k k0 of-    EQ => Just v0-    LT =>-      let (_ ** (t, _)) = toBlack l in-            lookup k t -- The checker can't tell that 't' is always -                       -- the same size as 'l'-    GT =>-      let (_ ** (t, _)) = toBlack r in-            lookup k t-
− test/reg006/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg006.idr --check-rm -f *.ibc
− test/reg007/A.lidr
@@ -1,5 +0,0 @@-> module A--> public export n : Nat-> n = ?lala-
test/reg007/expected view
@@ -1,6 +1,5 @@ reg007.lidr:8:1:A.n is already defined-reg007.lidr:12:11-17:-When checking right hand side of hurrah with expected type+reg007.lidr:12:11-17:When checking right hand side of hurrah with expected type         0 = 1  Type mismatch between
− test/reg007/reg007.lidr
@@ -1,12 +0,0 @@-> module B--> import A--> isSame  : A.n = A.lala-> isSame  = Refl--> A.n     = Z    -- This is where it's at!-> A.lala  = S Z--> hurrah  : Z = S Z-> hurrah  = isSame
− test/reg010/expected
@@ -1,3 +0,0 @@-reg010.idr:5:15:-When checking left hand side of with block in usubst.unsafeSubst:-Can't match on with block in usubst.unsafeSubst warg a P x x px
− test/reg010/reg010.idr
@@ -1,5 +0,0 @@-module usubst--total unsafeSubst : (P : a -> Type) -> (x : a) -> (y : a) -> P x -> P y-unsafeSubst P x y px with (Z)-  unsafeSubst P x x px | _ = px
− test/reg010/run
@@ -1,2 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg010.idr --check --nocolour
− test/reg018/expected
@@ -1,12 +0,0 @@-reg018a.idr:16:1:-conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat --> conat.minusCoNat-reg018a.idr:21:1:-conat.loopForever is possibly not total due to: conat.minusCoNat-reg018b.idr:8:1:-A.showB is possibly not total due to recursive path A.showB --> A.showB-reg018b.idr:11:1:-A.B implementation of Prelude.Show.Show is possibly not total due to: A.showB-reg018c.idr:21:1:-CodataTest.inf is possibly not total due to: with block in CodataTest.inf-reg018d.idr:8:1:-Main.pull is not total as there are missing cases
− test/reg018/reg018a.idr
@@ -1,21 +0,0 @@-module conat--%default total--codata CoNat = Z | S CoNat--infinity : CoNat-infinity = S infinity--plusCoNat : CoNat -> CoNat -> CoNat-plusCoNat Z x = x-plusCoNat (S x) y = S (plusCoNat x y)----I don't think this should be definable-minusCoNat : CoNat -> CoNat -> CoNat-minusCoNat Z n = Z-minusCoNat (S n) Z = S n-minusCoNat (S n) (S m) = plusCoNat Z (minusCoNat n m)--loopForever : CoNat-loopForever = minusCoNat infinity infinity
− test/reg018/reg018b.idr
@@ -1,14 +0,0 @@-module A--%default total--codata B = Z B | I B--showB : B -> String-showB (I x) = "I" ++ showB x-showB (Z x) = "Z" ++ showB x--Show B where show = showB--os : B-os = Z os
− test/reg018/reg018c.idr
@@ -1,22 +0,0 @@-module CodataTest-import Data.Vect--%default total--codata InfStream a = (::) a (InfStream a)------ natStream : InfStream Nat--- natStream = natFromStream 0 where---   natFromStream : Nat -> InfStream Nat---   natFromStream n = (::) n (natFromStream (S n))--take : (n: Nat) -> InfStream a -> Vect n a-take Z _ = []-take (S n) (x :: xs) = x :: CodataTest.take n xs--hdtl : InfStream a -> (a, InfStream a)-hdtl (x :: xs) = (x, xs)--inf : InfStream a -> InfStream a-inf (x :: xs) with (hdtl xs)-  | (hd, tl) = inf xs
− test/reg018/reg018d.idr
@@ -1,15 +0,0 @@-module Main--import Data.Vect-import Data.Fin--total-pull : Fin (S n) -> Vect (S n) a -> (a, Vect n a)-pull {n=Z}   _      (x :: xs) = (x, xs)--- pull {n=S q} FZ     (Vect.(::) {n=S _} x xs) = (x, xs)-pull {n=S _} (FS n) (x :: xs) =-  let (v, vs) = pull n xs in-        (v, x::vs)--main : IO ()-main = printLn (pull FZ [0, 1, 2])
− test/reg018/run
@@ -1,6 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg018a.idr --check-${IDRIS:-idris} $@ reg018b.idr --check-${IDRIS:-idris} $@ reg018c.idr --check-${IDRIS:-idris} $@ reg018d.idr --check-rm *.ibc
− test/reg023/expected
@@ -1,8 +0,0 @@-reg023.idr:7:5:-When checking right hand side of bad with expected type-        f Nat--Type mismatch between-        Nat (Type of 0)-and-        f Nat (Expected type)
− test/reg023/reg023.idr
@@ -1,8 +0,0 @@-module Foo--f : Type -> Type-f x = f x--bad : f Nat-bad = Z-
− test/reg023/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour reg023.idr --check-rm -f *.ibc
test/reg027/expected view
@@ -1,4 +1,3 @@ <<int fn>> 6-reg027a.idr:9:16:-Overlapping implementation: Show (Int -> a) already defined+reg027a.idr:9:16:Overlapping implementation: Show (Int -> a) already defined
− test/reg028/expected
@@ -1,6 +0,0 @@-reg028.idr:5:1:-tbad.bad is possibly not total due to: with block in tbad.bad-reg028a.idr:17:14-19:-This style of tactic proof is deprecated. See %runElab for the replacement.-reg028a.idr:11:1:-tbad.qsort' is possibly not total due to: with block in tbad.qsort'
− test/reg028/reg028.idr
@@ -1,8 +0,0 @@-module tbad--total-bad : Nat -> Nat-bad Z = Z-bad (S m) with (succ m)-    bad _ | j = bad j-
− test/reg028/reg028a.idr
@@ -1,25 +0,0 @@-module tbad--partial-qsort : Ord a => List a -> List a-qsort [] = []-qsort (x::xs) with (partition (<x) xs)-  qsort (x::xs) | (ys, zs) = qsort ys ++ [x] ++ qsort zs--total-qsort' : Ord a => List a -> List a-qsort' [] = []-qsort' (x::xs) with (partition (<x) xs)-  qsort' (x::xs) | (ys, zs) = ?qsortLemma------------ Proofs ------------qsortLemma = proof-  intros-  let ys' = qsort' ys-  let zs' = qsort' zs-  let ws = ys' ++ [x] ++ zs'-  trivial---
− test/reg028/run
@@ -1,4 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg028.idr --check-${IDRIS:-idris} $@ reg028a.idr --check-rm -f *.ibc
+ test/reg029/Reg029Wrapper.java view
@@ -0,0 +1,17 @@+import java.util.Map;++/**+ * The Java back end uses properties+ * instead of environment variables.+ * This wrapper loads the env variables+ * into the standard set of properties.+ */+public class Reg029Wrapper {+  public static void main(String args[]) {+    Map<String, String> env = System.getenv();+    for (String key : env.keySet()) {+      System.setProperty(key, env.get(key));+    }+    reg029.main(args);+  }+}
− test/reg034/expected
@@ -1,4 +0,0 @@-reg034.idr:6:5:When checking left hand side of bar:-Can't match on bar xs xs Refl-reg034.idr:9:5:When checking left hand side of foo:-Can't match on foo f x x Refl
− test/reg034/reg034.idr
@@ -1,10 +0,0 @@-module main-import Prelude.List--bar : (xs : List ()) -> (ys : List ()) -> -      Prelude.List.length xs = Prelude.List.length ys -> xs = ys-bar xs xs Refl = Refl--foo : (f : Nat -> Nat) -> (x : Nat) -> (y : Nat) -> f x = f y -> x = y-foo f x x Refl = Refl-
− test/reg034/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour --check reg034.idr-rm -f reg034 *.ibc
− test/reg035/expected
@@ -1,1 +0,0 @@-reg035b.idr:8:6:No such variable __pi_arg
− test/reg035/reg035.idr
@@ -1,15 +0,0 @@-elimId : (a : Type) ->-         (a1 : a) ->-         (a2 : a) ->-         (m : (x : a) -> (y : a) -> x = y -> Type) ->-         (f : (x : a) -> m x x Refl) ->-         (id : a1 = a2) ->-         m a1 a2 id-elimId _ x _ _ f Refl = f x--tran : (a : Type) -> (b : a) -> (c : a) -> (d : a) ->  -       (e : b = c) ->  (f : c = d) ->  b = d-tran = \ a : Type , b : a , c : a , d : a , e : b = c =>-    (elimId a b c (\ f : a , g : a , h : f = g => -                         (i : a) ->  (j : g = i) ->  f = i)-                 (\ f : a , g : a , h : f = g =>  h) e d)
− test/reg035/reg035a.lidr
@@ -1,67 +0,0 @@-> module Set--> import Data.So--> %default total--> postulate soAndIntro : (p : alpha -> Bool) ->->                        (q : beta -> Bool) -> ->                        (a : alpha) ->->                        (b : beta) ->->                        So (p a) ->->                        So (q b) ->->                        So (p a && q b)--> hasNoDuplicates : (Eq alpha) => List alpha -> Bool-> hasNoDuplicates as = as == nub as--> setEq : (Eq alpha) => List alpha -> List alpha -> Bool-> setEq Nil Nil = True-> setEq Nil (y :: ys) = False-> setEq (x :: xs) Nil = False-> setEq {alpha} (x :: xs) (y :: ys) =->   assert_total $ (x == y && setEq xs ys) ->   ||->   (elem x ys && elem y xs && ->    setEq (filter (/= y) xs) (filter (/= x) ys)->   )--> data Set : Type -> Type where->   Setify : (as : List a) -> Set a--> implementation (Eq a) => Eq (Set a) where->   (==) (Setify as) (Setify bs) = setEq as bs--> postulate reflexive_Set_eqeq : (Eq a) => ->                                (as : Set a) -> ->                                So (as == as)--> unwrap : Set a -> List a-> unwrap (Setify as) = as--> union : Set (Set a) -> Set a-> union (Setify ss) = Setify (concat (map unwrap ss)) --> listify : (Eq a) => Set a -> List a-> listify = nub . unwrap--> arePairwiseDisjoint : (Eq a) => Set (Set a) -> Bool-> arePairwiseDisjoint (Setify ss) = ->   hasNoDuplicates (concat (map listify ss))--> isPartition : (Eq a) => Set (Set a) -> Set a -> Bool-> isPartition ass as = arePairwiseDisjoint ass && union ass == as--> partitionLemma0 : (Eq alpha) => ->                   (ass : Set (Set alpha)) -> ->                   So (arePairwiseDisjoint ass) ->->                   So (ass `isPartition` union ass)-> partitionLemma0 ass asspd = (soAndIntro (\ xss => arePairwiseDisjoint xss)->                                        (\ xs => union ass == xs)->                                        ass->                                        (union ass)->                                        asspd ->                                        uasseqas) where->   uasseqas : So (union ass == union ass)->   uasseqas = reflexive_Set_eqeq (union ass)-
− test/reg035/reg035b.idr
@@ -1,12 +0,0 @@-import Data.Vect-import Data.Fin--total-finZEmpty : Fin Z -> a--fins : (n : Nat) -> (xs : Vect n (Fin n) ** ((x : Fin n) -> Elem x xs))-fins Z     = ([] ** (finZEmpty {a=_}))---- f : (a : Nat) -> a = S a -> Void--- f a = believe_me-
− test/reg035/run
@@ -1,5 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour --check reg035.idr-${IDRIS:-idris} $@ --nocolour --check reg035a.lidr-${IDRIS:-idris} $@ --nocolour --check reg035b.idr-rm -f *.ibc
test/reg039/run view
@@ -1,35 +1,8 @@ #!/usr/bin/env bash --declare -a extraargs-for arg in "$@"-do-    extraargs=("${extraargs[@]}" "'$arg'")-done-if (which timeout&>/dev/null); then-  timeout 60 ${IDRIS:-idris} $@ --nocolour reg039.idr --exec go-else-    # From http://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting-    # Executes command with a timeout-    # Params:-    #   $1 timeout in seconds-    #   $2 command-    # Returns 1 if timed out 0 otherwise-    timeout() {--        time=$1--        # start the command in a subshell to avoid problem with pipes-        # (spawn accepts one command)-        command="/bin/sh -c \"$2\""--        expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"+set -eu -        if [ $? = 1 ] ; then-            echo "Timeout after ${time} seconds"-        fi+TIMEOUT=../scripts/timeout -    }-    timeout 60 "${IDRIS:-idris} ${extraargs[*]} --nocolour reg039.idr --exec go"-    fi-    rm -f reg039 *.ibc+$TIMEOUT 60 "${IDRIS:-idris}" "$@" --nocolour reg039.idr --exec go+rm -f *.ibc
test/reg040/reg040.idr view
@@ -1,7 +1,7 @@ -- The regression that this tests for is defunct unsafePerformIO  io : IO Int-io = return 42+io = pure 42  main : IO () main = printLn $ unsafePerformIO io
− test/reg044/expected
@@ -1,16 +0,0 @@-reg044.idr:4:6-11:-This style of tactic proof is deprecated. See %runElab for the replacement.-reg044.idr:4:4:-When checking right hand side of Main.pf with expected type-        (b : Nat) -> (a : Nat) -> (S a = S b) -> a = b--Type mismatch between-        b = b (Type of Refl)-and-        a = b (Expected type)--Specifically:-        Type mismatch between-                b-        and-                a
− test/reg044/reg044.idr
@@ -1,6 +0,0 @@-exjection : S a = S b -> a = b-exjection = ?pf--pf = proof-  intros-  refine Refl
− test/reg044/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour reg044.idr --check-rm -f *.ibc
test/reg048/reg048.idr view
@@ -10,7 +10,7 @@                         if length found /= n                             then putStrLn $ "some lost in " ++ show xs ++ ": res=" ++ show res                                              ++ " toList=" ++ show lst-                           else return ()+                           else pure ()    where       mp : SortedMap Int ()
− test/reg049/expected
@@ -1,7 +0,0 @@-reg049.idr:2:9:When checking constructor Main.Bogus:-Void is not Main.Foo-reg049.idr:5:6:-When checking right hand side of uhOh with expected type-        Void--No such variable Bogus
− test/reg049/reg049.idr
@@ -1,5 +0,0 @@-data Foo : Type where-  Bogus : Void--uhOh : Void-uhOh = Bogus
− test/reg049/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour --check $@ reg049.idr-rm -f *.ibc
− test/reg050/badbangop.idr
@@ -1,15 +0,0 @@-module badbangop---- Check that using "!" by itself as an operator does not work--infixl 2 !--(!) : List a -> Nat -> Maybe a-xs ! n = index' n xs--aList : List Integer-aList = [1,2,3,4,5]--opUse : Maybe Integer-opUse = aList ! 2-
− test/reg050/baddoublebang.idr
@@ -1,7 +0,0 @@-module baddoublebang---- Check that two bang bindings running together don't work--doubleBang : Maybe (Maybe Nat) -> Maybe Nat-doubleBang mmn = do pure !!mmn-
− test/reg050/expected
@@ -1,10 +0,0 @@-./badbangop.idr:7:1: error: ! is-    not a valid-    operator, expected: space-(!) : List a -> Nat -> Maybe a -^                              -./baddoublebang.idr:6:28: error: unexpected-    Operator without known fixity:-    !!, expected: space-doubleBang mmn = do pure !!mmn -                           ^   
− test/reg050/run
@@ -1,5 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour --check working.idr-${IDRIS:-idris} $@ --nocolour --check badbangop.idr-${IDRIS:-idris} $@ --nocolour --check baddoublebang.idr-rm -f *.ibc
− test/reg050/working.idr
@@ -1,21 +0,0 @@-module working---- Check that using an operator beginning with "!" works--infixl 2 !!--(!!) : List a -> Nat -> Maybe a-xs !! n = index' n xs--aList : List Integer-aList = [1,2,3,4,5]--opUse : Maybe Integer-opUse = aList !! 2--opUseWithBang : Maybe Nat -> Maybe Integer-opUseWithBang mn = do aList !! !mn--doubleBang : Maybe (Maybe Nat) -> Maybe Nat-doubleBang mmn = do pure ! !mmn-
test/reg052/reg052.idr view
@@ -1,8 +1,8 @@ impure_op : Bits64 -> IO Bits64-impure_op foo = return $ foo + 1+impure_op foo = pure $ foo + 1  impure_int : IO Int-impure_int = return 41+impure_int = pure 41  main : IO () main = impure_int >>= impure_op . prim__zextInt_B64 >>= printLn
− test/reg054/expected
@@ -1,13 +0,0 @@-reg054.idr:18:5:When checking left hand side of inf:-When checking an application of constructor Main.MkInfer:-        Attempting concrete match on polymorphic argument: 0-reg054.idr:34:7:When checking left hand side of weird:-No explicit types on left hand side: Char-reg054.idr:37:8:When checking left hand side of weird':-No explicit types on left hand side: Nat-reg054.idr:40:1-8:When checking left hand side of tctrick:-When checking an application of Main.tctrick:-        Type mismatch between-                Maybe a1 (Type of Just x)-        and-                a (Expected type)
− test/reg054/reg054.idr
@@ -1,42 +0,0 @@--- Catch typecase--data Ty = MInt | Str--eval : Ty -> Type-eval MInt = Maybe Int -eval Str = String--tcok : (x : Ty) -> eval x -> Int-tcok MInt (Just x) = x-tcok Str "foo" = 42-tcok Str x = 100--data Infer : Type where-     MkInfer : (a : Type) -> a -> Infer--inf : Infer -> Bool-inf (MkInfer _ Z) = True-inf (MkInfer _ (S k)) = False--data InfView : Infer -> Type where-     INat : (x : Nat) -> InfView (MkInfer Nat x)--foo : (i : Infer) -> InfView i -> Nat-foo (MkInfer _ _) (INat Z) = Z-foo (MkInfer _ _) (INat (S k)) = k--data Weird : Type -> Type where-     WInt : Int -> Weird Int-     WStr : String -> Weird String-     WBot : Weird Void--weird : Weird x -> x-weird {x = Char} y = '5'--weird' : Weird x -> x-weird' {x = Prelude.Nat.Nat} y = Z--tctrick : a -> Int-tctrick (Just x) = x-tctrick Nothing = 42-
− test/reg054/run
@@ -1,2 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour reg054.idr --check
− test/reg055/expected
@@ -1,9 +0,0 @@-reg055.idr:5:3:When checking left hand side of g:-Can't match on g (f 0)-reg055.idr:8:3:When checking left hand side of h:-Can't match on h x x-reg055a.idr:8:5:When checking left hand side of foo:-When checking an application of constructor Foo.CAny:-        Attempting concrete match on polymorphic argument: Nothing-reg055a.idr:13:7:When checking left hand side of Foo.apply:-Can't match on apply (\x => \y => x) a
− test/reg055/reg055.idr
@@ -1,26 +0,0 @@-f : Nat -> Nat -f Z = Z     --g : Nat -> Nat -g (f Z) = 1    --h : Int -> Int -> Int-h x x = x--data Parity : Nat -> Type where-     Even : Parity (n + n)-     Odd  : Parity (S (n + n))--foo : (n : Nat) -> Parity n -> Bool-foo (plus k k) Even = False-foo (S (plus k k)) Odd = True--data EqualLists : List () -> List () -> Type where-  EL : EqualLists l l--shouldWork : (l1,l2:List ()) -> EqualLists l1 l2 -> Bool-shouldWork [] [] EL = ?shouldWork_rhs_2-shouldWork (x :: xs) (x :: xs) EL = ?shouldWork_rhs_3---- shouldWork [] [] EL = ?x_1--- shouldWork (x :: xs) (x :: xs) EL = ?x_2
− test/reg055/reg055a.idr
@@ -1,15 +0,0 @@-module Foo--data Cheat : Type -> Type where-     CAny : a -> Cheat a-     CInt : Cheat Int--foo : Cheat a -> Int-foo (CAny Nothing) = 42 -foo (CAny (Just x)) = 43 -foo CInt = 0 --apply : (a -> a -> b) -> a -> a-apply (\x => \y => x) a = a-apply f a = a -
− test/reg055/run
@@ -1,5 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour reg055.idr --check-${IDRIS:-idris} $@ --nocolour reg055a.idr --check-rm -f *.ibc-
− test/reg056/expected
@@ -1,2 +0,0 @@-reg056.idr:7:7:dodgy n m Refl is a valid case-reg056.idr:10:6:nonk Refl is a valid case
− test/reg056/reg056.idr
@@ -1,14 +0,0 @@-k : (a : Type) -> (x, y : a) -> (p, q : x = y) -> p = q-k a x x Refl Refl = Refl--postulate trap : Z = Z--dodgy : (a, b : ()) -> a = b -> Void-dodgy n m Refl impossible--nonk : (Main.trap = Refl {x = Z}) -> Void-nonk Refl impossible--false : Void-false = nonk (k Nat Z Z trap Refl)-
− test/reg056/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg056.idr -o reg056-rm -f *.ibc
− test/reg068/expected
@@ -1,9 +0,0 @@-reg068.idr:1:6:-Main.nat has a name which may be implicitly bound.-This is likely to lead to problems!-reg068.idr:2:6:Main.ze has a name which may be implicitly bound.-This is likely to lead to problems!-reg068.idr:2:8-11:WARNING: nat is bound as an implicit-	Did you mean to refer to Main.nat?-reg068.idr:2:6:When checking constructor Main.ze:-Type level variable nat is not Main.nat
− test/reg068/reg068.idr
@@ -1,4 +0,0 @@-data nat : Type where --error-  ze : nat --hello.idr:10:6:When checking constructor Main.ze: !!V 0!! is not Main.nat-  su : nat -> nat-
− test/reg068/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg068.idr --check-rm -f *.ibc
− test/reg069/Mod.idr
@@ -1,12 +0,0 @@-module Mod---- %access public--export-natfn : Nat -> Nat-natfn n = (S (S n))--public export-natexp : (n : Nat) -> Nat-natexp k = S (natfn k)-
− test/reg069/expected
@@ -1,2 +0,0 @@-Mod.idr:11:1:-public export Mod.natexp can't refer to export Mod.natfn
− test/reg069/reg069.idr
@@ -1,5 +0,0 @@-import Mod--foo : natexp 4 = 7-foo = Refl-
− test/reg069/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg069.idr --check-rm -f *.ibc
− test/reg070/expected
@@ -1,2 +0,0 @@-reg070.idr:7:1:-Test_show.Te implementation of Prelude.Show.Show is possibly not total due to: Prelude.Show.Test_show.Te implementation of Prelude.Show.Show, method show
− test/reg070/reg070.idr
@@ -1,15 +0,0 @@-module Test_show--%default total--data Te = C1 | C2 | C3--Show Te where-    show C1 = "C1"---- Eq Te where---     (==) C1 C3 = False---- foo : Te -> String--- foo = show-
− test/reg070/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ reg070.idr --check-rm -f *.ibc
− test/reg072/DoubleEquality.idr
@@ -1,5 +0,0 @@-module DoubleEquality--oops : Void-oops = the ((False = True) -> Void) (\Refl impossible) $ cong {f = (>0) . (1/)} $ the (-0.0 = 0.0) Refl-
− test/reg072/expected
@@ -1,15 +0,0 @@-DoubleEquality.idr:4:87:-When checking right hand side of oops with expected type-        Void--When checking argument value to function Prelude.Basics.the:-        Type mismatch between-                x = x (Type of Refl)-        and-                (-0.0) = 0.0 (Expected type)-        -        Specifically:-                Type mismatch between-                        -0.0-                and-                        0.0
− test/reg072/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ DoubleEquality.idr --check-rm -f *.ibc
test/regression001/reg065.idr view
@@ -2,7 +2,7 @@ ||| ||| Fixes a regression where previous methods used in a later method's ||| type would lead to "can't find interface" errors-module TypeClassDep+module InterfaceDep  import Data.Vect 
+ test/regression002/A.lidr view
@@ -0,0 +1,5 @@+> module A++> public export n : Nat+> n = ?lala+
+ test/regression002/DoubleEquality.idr view
@@ -0,0 +1,5 @@+module DoubleEquality++oops : Void+oops = the ((False = True) -> Void) (\Refl impossible) $ cong {f = (>0) . (1/)} $ the (-0.0 = 0.0) Refl+
+ test/regression002/Mod.idr view
@@ -0,0 +1,12 @@+module Mod++-- %access public++export+natfn : Nat -> Nat+natfn n = (S (S n))++public export+natexp : (n : Nat) -> Nat+natexp k = S (natfn k)+
+ test/regression002/badbangop.idr view
@@ -0,0 +1,15 @@+module badbangop++-- Check that using "!" by itself as an operator does not work++infixl 2 !++(!) : List a -> Nat -> Maybe a+xs ! n = index' n xs++aList : List Integer+aList = [1,2,3,4,5]++opUse : Maybe Integer+opUse = aList ! 2+
+ test/regression002/baddoublebang.idr view
@@ -0,0 +1,7 @@+module baddoublebang++-- Check that two bang bindings running together don't work++doubleBang : Maybe (Maybe Nat) -> Maybe Nat+doubleBang mmn = do pure !!mmn+
+ test/regression002/expected view
@@ -0,0 +1,147 @@+reg003a.idr:4:11:When checking type of Main.ECons:+No such variable OddList+reg003a.idr:7:11:When checking type of Main.OCons:+No such variable EvenList+reg003a.idr:9:6:When checking type of Main.test:+No such variable EvenList+reg006.idr:17:1:+RBTree.lookup is possibly not total due to recursive path RBTree.lookup --> RBTree.lookup+reg007.lidr:8:1:A.n is already defined+reg007.lidr:12:11-17:When checking right hand side of hurrah with expected type+        0 = 1++Type mismatch between+        n = lala (Type of isSame)+and+        0 = 1 (Expected type)++Specifically:+        Type mismatch between+                1+        and+                0+reg010.idr:5:15:+When checking left hand side of with block in usubst.unsafeSubst:+Can't match on with block in usubst.unsafeSubst warg a P x x px+reg018a.idr:16:1:+conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat --> conat.minusCoNat+reg018a.idr:21:1:+conat.loopForever is possibly not total due to: conat.minusCoNat+reg018b.idr:8:1:+A.showB is possibly not total due to recursive path A.showB --> A.showB+reg018b.idr:11:1:+A.B implementation of Prelude.Show.Show is possibly not total due to: A.showB+reg018c.idr:21:1:+CodataTest.inf is possibly not total due to: with block in CodataTest.inf+reg018d.idr:8:1:Main.pull is not total as there are missing cases+reg023.idr:7:5:When checking right hand side of bad with expected type+        f Nat++Type mismatch between+        Nat (Type of 0)+and+        f Nat (Expected type)+reg028.idr:5:1:tbad.bad is possibly not total due to: with block in tbad.bad+reg028a.idr:17:14-19:+This style of tactic proof is deprecated. See %runElab for the replacement.+reg028a.idr:11:1:+tbad.qsort' is possibly not total due to: with block in tbad.qsort'+reg034.idr:6:5:When checking left hand side of bar:+Can't match on bar xs xs Refl+reg034.idr:9:5:When checking left hand side of foo:+Can't match on foo f x x Refl+reg035b.idr:8:6:No such variable __pi_arg+reg044.idr:4:6-11:+This style of tactic proof is deprecated. See %runElab for the replacement.+reg044.idr:4:4:When checking right hand side of Main.pf with expected type+        (b : Nat) -> (a : Nat) -> (S a = S b) -> a = b++Type mismatch between+        b = b (Type of Refl)+and+        a = b (Expected type)++Specifically:+        Type mismatch between+                b+        and+                a+reg049.idr:2:9:When checking constructor Main.Bogus:+Void is not Main.Foo+reg049.idr:5:6:When checking right hand side of uhOh with expected type+        Void++No such variable Bogus+./badbangop.idr:7:1: error: ! is+    not a valid+    operator, expected: space+(!) : List a -> Nat -> Maybe a +^                              +./baddoublebang.idr:6:28: error: unexpected+    Operator without known fixity:+    !!, expected: space+doubleBang mmn = do pure !!mmn +                           ^   +reg054.idr:18:5:When checking left hand side of inf:+When checking an application of constructor Main.MkInfer:+        Attempting concrete match on polymorphic argument: 0+reg054.idr:34:7:When checking left hand side of weird:+No explicit types on left hand side: Char+reg054.idr:37:8:When checking left hand side of weird':+No explicit types on left hand side: Nat+reg054.idr:40:1-8:When checking left hand side of tctrick:+When checking an application of Main.tctrick:+        Type mismatch between+                Maybe a1 (Type of Just x)+        and+                a (Expected type)+reg055.idr:5:3:When checking left hand side of g:+Can't match on g (f 0)+reg055.idr:8:3:When checking left hand side of h:+Can't match on h x x+reg055a.idr:8:5:When checking left hand side of foo:+When checking an application of constructor Foo.CAny:+        Attempting concrete match on polymorphic argument: Nothing+reg055a.idr:13:7:When checking left hand side of Foo.apply:+Can't match on apply (\x => \y => x) a+reg056.idr:7:7:dodgy n m Refl is a valid case+reg056.idr:10:6:nonk Refl is a valid case+reg068.idr:1:6:Main.nat has a name which may be implicitly bound.+This is likely to lead to problems!+reg068.idr:2:6:Main.ze has a name which may be implicitly bound.+This is likely to lead to problems!+reg068.idr:2:8-11:WARNING: nat is bound as an implicit+	Did you mean to refer to Main.nat?+reg068.idr:2:6:When checking constructor Main.ze:+Type level variable nat is not Main.nat+Mod.idr:11:1:public export Mod.natexp can't refer to export Mod.natfn+reg070.idr:7:1:+Test_show.Te implementation of Prelude.Show.Show is possibly not total due to: Prelude.Show.Test_show.Te implementation of Prelude.Show.Show, method show+./reg076.idr:8:1: error: Missing+    fixity declaration for+    Main.:>, expected: "->", "=>",+    ambiguous use of a left-associative operator,+    ambiguous use of a non-associative operator,+    ambiguous use of a right-associative operator+<EOF> +^     +./reg077.idr:3:1: error: Missing+    fixity declaration for+    Main.:>>, expected: ")", ";",+    "in", start of block+<EOF> +^     +DoubleEquality.idr:4:87:When checking right hand side of oops with expected type+        Void++When checking argument value to function Prelude.Basics.the:+        Type mismatch between+                x = x (Type of Refl)+        and+                (-0.0) = 0.0 (Expected type)+        +        Specifically:+                Type mismatch between+                        -0.0+                and+                        0.0
+ test/regression002/reg003.idr view
@@ -0,0 +1,13 @@++mutual+  namespace Even+    data EvenList : Type where+        Nil  : EvenList+        (::) : Nat -> OddList -> EvenList++  namespace Odd+    data OddList : Type where+        (::) : Nat -> EvenList -> OddList++test : EvenList+test = [1, 2, 3, 4, 5, 6]
+ test/regression002/reg003a.idr view
@@ -0,0 +1,10 @@++data EvenList : Type where+    ENil  : EvenList+    ECons : Nat -> OddList -> EvenList++data OddList : Type where+    OCons : Nat -> EvenList -> OddList++test : EvenList+test = ECons 1 ENil
+ test/regression002/reg006.idr view
@@ -0,0 +1,28 @@+module RBTree++data Colour = Red | Black++data RBTree : Type -> Type -> Nat -> Colour -> Type where+  Leaf : RBTree k v Z Black+  RedBranch : k -> v -> RBTree k v n Black -> RBTree k v n Black -> RBTree k v n Red+  BlackBranch : k -> v -> RBTree k v n x -> RBTree k v n y -> RBTree k v (S n) Black++toBlack : RBTree k v n c -> (m ** (RBTree k v m Black, Either (m = n) (m = (S n))))+toBlack (RedBranch k v l r) = (_ ** (BlackBranch k v l r, Right Refl))+toBlack Leaf = (_ ** (Leaf, Left Refl))+toBlack (BlackBranch k v l r) = (_ ** (BlackBranch k v l r, Left Refl))++total -- Yes, but the checker can't spot it+lookup : Ord k => k -> RBTree k v n Black -> Maybe v+lookup k Leaf = Nothing+lookup k (BlackBranch k0 v0 l r) =+  case compare k k0 of+    EQ => Just v0+    LT =>+      let (_ ** (t, _)) = toBlack l in+            lookup k t -- The checker can't tell that 't' is always +                       -- the same size as 'l'+    GT =>+      let (_ ** (t, _)) = toBlack r in+            lookup k t+
+ test/regression002/reg007.lidr view
@@ -0,0 +1,12 @@+> module B++> import A++> isSame  : A.n = A.lala+> isSame  = Refl++> A.n     = Z    -- This is where it's at!+> A.lala  = S Z++> hurrah  : Z = S Z+> hurrah  = isSame
+ test/regression002/reg010.idr view
@@ -0,0 +1,5 @@+module usubst++total unsafeSubst : (P : a -> Type) -> (x : a) -> (y : a) -> P x -> P y+unsafeSubst P x y px with (Z)+  unsafeSubst P x x px | _ = px
+ test/regression002/reg018a.idr view
@@ -0,0 +1,21 @@+module conat++%default total++codata CoNat = Z | S CoNat++infinity : CoNat+infinity = S infinity++plusCoNat : CoNat -> CoNat -> CoNat+plusCoNat Z x = x+plusCoNat (S x) y = S (plusCoNat x y)++--I don't think this should be definable+minusCoNat : CoNat -> CoNat -> CoNat+minusCoNat Z n = Z+minusCoNat (S n) Z = S n+minusCoNat (S n) (S m) = plusCoNat Z (minusCoNat n m)++loopForever : CoNat+loopForever = minusCoNat infinity infinity
+ test/regression002/reg018b.idr view
@@ -0,0 +1,14 @@+module A++%default total++codata B = Z B | I B++showB : B -> String+showB (I x) = "I" ++ showB x+showB (Z x) = "Z" ++ showB x++Show B where show = showB++os : B+os = Z os
+ test/regression002/reg018c.idr view
@@ -0,0 +1,22 @@+module CodataTest+import Data.Vect++%default total++codata InfStream a = (::) a (InfStream a)+--+-- natStream : InfStream Nat+-- natStream = natFromStream 0 where+--   natFromStream : Nat -> InfStream Nat+--   natFromStream n = (::) n (natFromStream (S n))++take : (n: Nat) -> InfStream a -> Vect n a+take Z _ = []+take (S n) (x :: xs) = x :: CodataTest.take n xs++hdtl : InfStream a -> (a, InfStream a)+hdtl (x :: xs) = (x, xs)++inf : InfStream a -> InfStream a+inf (x :: xs) with (hdtl xs)+  | (hd, tl) = inf xs
+ test/regression002/reg018d.idr view
@@ -0,0 +1,15 @@+module Main++import Data.Vect+import Data.Fin++total+pull : Fin (S n) -> Vect (S n) a -> (a, Vect n a)+pull {n=Z}   _      (x :: xs) = (x, xs)+-- pull {n=S q} FZ     (Vect.(::) {n=S _} x xs) = (x, xs)+pull {n=S _} (FS n) (x :: xs) =+  let (v, vs) = pull n xs in+        (v, x::vs)++main : IO ()+main = printLn (pull FZ [0, 1, 2])
+ test/regression002/reg023.idr view
@@ -0,0 +1,8 @@+module Foo++f : Type -> Type+f x = f x++bad : f Nat+bad = Z+
+ test/regression002/reg028.idr view
@@ -0,0 +1,8 @@+module tbad++total+bad : Nat -> Nat+bad Z = Z+bad (S m) with (succ m)+    bad _ | j = bad j+
+ test/regression002/reg028a.idr view
@@ -0,0 +1,25 @@+module tbad++partial+qsort : Ord a => List a -> List a+qsort [] = []+qsort (x::xs) with (partition (<x) xs)+  qsort (x::xs) | (ys, zs) = qsort ys ++ [x] ++ qsort zs++total+qsort' : Ord a => List a -> List a+qsort' [] = []+qsort' (x::xs) with (partition (<x) xs)+  qsort' (x::xs) | (ys, zs) = ?qsortLemma++---------- Proofs ----------++qsortLemma = proof+  intros+  let ys' = qsort' ys+  let zs' = qsort' zs+  let ws = ys' ++ [x] ++ zs'+  trivial+++
+ test/regression002/reg034.idr view
@@ -0,0 +1,10 @@+module main+import Prelude.List++bar : (xs : List ()) -> (ys : List ()) -> +      Prelude.List.length xs = Prelude.List.length ys -> xs = ys+bar xs xs Refl = Refl++foo : (f : Nat -> Nat) -> (x : Nat) -> (y : Nat) -> f x = f y -> x = y+foo f x x Refl = Refl+
+ test/regression002/reg035.idr view
@@ -0,0 +1,15 @@+elimId : (a : Type) ->+         (a1 : a) ->+         (a2 : a) ->+         (m : (x : a) -> (y : a) -> x = y -> Type) ->+         (f : (x : a) -> m x x Refl) ->+         (id : a1 = a2) ->+         m a1 a2 id+elimId _ x _ _ f Refl = f x++tran : (a : Type) -> (b : a) -> (c : a) -> (d : a) ->  +       (e : b = c) ->  (f : c = d) ->  b = d+tran = \ a : Type , b : a , c : a , d : a , e : b = c =>+    (elimId a b c (\ f : a , g : a , h : f = g => +                         (i : a) ->  (j : g = i) ->  f = i)+                 (\ f : a , g : a , h : f = g =>  h) e d)
+ test/regression002/reg035a.lidr view
@@ -0,0 +1,67 @@+> module Set++> import Data.So++> %default total++> postulate soAndIntro : (p : alpha -> Bool) ->+>                        (q : beta -> Bool) -> +>                        (a : alpha) ->+>                        (b : beta) ->+>                        So (p a) ->+>                        So (q b) ->+>                        So (p a && q b)++> hasNoDuplicates : (Eq alpha) => List alpha -> Bool+> hasNoDuplicates as = as == nub as++> setEq : (Eq alpha) => List alpha -> List alpha -> Bool+> setEq Nil Nil = True+> setEq Nil (y :: ys) = False+> setEq (x :: xs) Nil = False+> setEq {alpha} (x :: xs) (y :: ys) =+>   assert_total $ (x == y && setEq xs ys) +>   ||+>   (elem x ys && elem y xs && +>    setEq (filter (/= y) xs) (filter (/= x) ys)+>   )++> data Set : Type -> Type where+>   Setify : (as : List a) -> Set a++> implementation (Eq a) => Eq (Set a) where+>   (==) (Setify as) (Setify bs) = setEq as bs++> postulate reflexive_Set_eqeq : (Eq a) => +>                                (as : Set a) -> +>                                So (as == as)++> unwrap : Set a -> List a+> unwrap (Setify as) = as++> union : Set (Set a) -> Set a+> union (Setify ss) = Setify (concat (map unwrap ss)) ++> listify : (Eq a) => Set a -> List a+> listify = nub . unwrap++> arePairwiseDisjoint : (Eq a) => Set (Set a) -> Bool+> arePairwiseDisjoint (Setify ss) = +>   hasNoDuplicates (concat (map listify ss))++> isPartition : (Eq a) => Set (Set a) -> Set a -> Bool+> isPartition ass as = arePairwiseDisjoint ass && union ass == as++> partitionLemma0 : (Eq alpha) => +>                   (ass : Set (Set alpha)) -> +>                   So (arePairwiseDisjoint ass) ->+>                   So (ass `isPartition` union ass)+> partitionLemma0 ass asspd = (soAndIntro (\ xss => arePairwiseDisjoint xss)+>                                        (\ xs => union ass == xs)+>                                        ass+>                                        (union ass)+>                                        asspd +>                                        uasseqas) where+>   uasseqas : So (union ass == union ass)+>   uasseqas = reflexive_Set_eqeq (union ass)+
+ test/regression002/reg035b.idr view
@@ -0,0 +1,12 @@+import Data.Vect+import Data.Fin++total+finZEmpty : Fin Z -> a++fins : (n : Nat) -> (xs : Vect n (Fin n) ** ((x : Fin n) -> Elem x xs))+fins Z     = ([] ** (finZEmpty {a=_}))++-- f : (a : Nat) -> a = S a -> Void+-- f a = believe_me+
+ test/regression002/reg044.idr view
@@ -0,0 +1,6 @@+exjection : S a = S b -> a = b+exjection = ?pf++pf = proof+  intros+  refine Refl
+ test/regression002/reg049.idr view
@@ -0,0 +1,5 @@+data Foo : Type where+  Bogus : Void++uhOh : Void+uhOh = Bogus
+ test/regression002/reg054.idr view
@@ -0,0 +1,42 @@+-- Catch typecase++data Ty = MInt | Str++eval : Ty -> Type+eval MInt = Maybe Int +eval Str = String++tcok : (x : Ty) -> eval x -> Int+tcok MInt (Just x) = x+tcok Str "foo" = 42+tcok Str x = 100++data Infer : Type where+     MkInfer : (a : Type) -> a -> Infer++inf : Infer -> Bool+inf (MkInfer _ Z) = True+inf (MkInfer _ (S k)) = False++data InfView : Infer -> Type where+     INat : (x : Nat) -> InfView (MkInfer Nat x)++foo : (i : Infer) -> InfView i -> Nat+foo (MkInfer _ _) (INat Z) = Z+foo (MkInfer _ _) (INat (S k)) = k++data Weird : Type -> Type where+     WInt : Int -> Weird Int+     WStr : String -> Weird String+     WBot : Weird Void++weird : Weird x -> x+weird {x = Char} y = '5'++weird' : Weird x -> x+weird' {x = Prelude.Nat.Nat} y = Z++tctrick : a -> Int+tctrick (Just x) = x+tctrick Nothing = 42+
+ test/regression002/reg055.idr view
@@ -0,0 +1,26 @@+f : Nat -> Nat +f Z = Z     ++g : Nat -> Nat +g (f Z) = 1    ++h : Int -> Int -> Int+h x x = x++data Parity : Nat -> Type where+     Even : Parity (n + n)+     Odd  : Parity (S (n + n))++foo : (n : Nat) -> Parity n -> Bool+foo (plus k k) Even = False+foo (S (plus k k)) Odd = True++data EqualLists : List () -> List () -> Type where+  EL : EqualLists l l++shouldWork : (l1,l2:List ()) -> EqualLists l1 l2 -> Bool+shouldWork [] [] EL = ?shouldWork_rhs_2+shouldWork (x :: xs) (x :: xs) EL = ?shouldWork_rhs_3++-- shouldWork [] [] EL = ?x_1+-- shouldWork (x :: xs) (x :: xs) EL = ?x_2
+ test/regression002/reg055a.idr view
@@ -0,0 +1,15 @@+module Foo++data Cheat : Type -> Type where+     CAny : a -> Cheat a+     CInt : Cheat Int++foo : Cheat a -> Int+foo (CAny Nothing) = 42 +foo (CAny (Just x)) = 43 +foo CInt = 0 ++apply : (a -> a -> b) -> a -> a+apply (\x => \y => x) a = a+apply f a = a +
+ test/regression002/reg056.idr view
@@ -0,0 +1,14 @@+k : (a : Type) -> (x, y : a) -> (p, q : x = y) -> p = q+k a x x Refl Refl = Refl++postulate trap : Z = Z++dodgy : (a, b : ()) -> a = b -> Void+dodgy n m Refl impossible++nonk : (Main.trap = Refl {x = Z}) -> Void+nonk Refl impossible++false : Void+false = nonk (k Nat Z Z trap Refl)+
+ test/regression002/reg068.idr view
@@ -0,0 +1,4 @@+data nat : Type where --error+  ze : nat --hello.idr:10:6:When checking constructor Main.ze: !!V 0!! is not Main.nat+  su : nat -> nat+
+ test/regression002/reg069.idr view
@@ -0,0 +1,5 @@+import Mod++foo : natexp 4 = 7+foo = Refl+
+ test/regression002/reg070.idr view
@@ -0,0 +1,15 @@+module Test_show++%default total++data Te = C1 | C2 | C3++Show Te where+    show C1 = "C1"++-- Eq Te where+--     (==) C1 C3 = False++-- foo : Te -> String+-- foo = show+
+ test/regression002/reg076.idr view
@@ -0,0 +1,7 @@++data Qux : a -> Type where+  Tux : String -> Qux a++data Bar : a -> Type where+  Nil : Bar a+  (:>) : Qux a -> Bar a -> Bar a
+ test/regression002/reg077.idr view
@@ -0,0 +1,2 @@++data (:>>) : a -> b -> Type where
+ test/regression002/run view
@@ -0,0 +1,37 @@+#!/usr/bin/env bash++${IDRIS:-idris} $@ --nobanner --nocolour --quiet <<!+:load reg003.idr+:load reg003a.idr+:load reg006.idr+:load reg007.lidr+:load reg010.idr+:load reg018a.idr+:load reg018b.idr+:load reg018c.idr+:load reg018d.idr+:load reg023.idr+:load reg028.idr+:load reg028a.idr+:load reg034.idr+:load reg035.idr+:load reg035a.lidr+:load reg035b.idr+:load reg044.idr+:load reg049.idr+:load working.idr+:load badbangop.idr+:load baddoublebang.idr+:load reg054.idr+:load reg055.idr+:load reg055a.idr+:load reg056.idr+:load reg068.idr+:load reg069.idr+:load reg070.idr+:load reg076.idr+:load reg077.idr+:load DoubleEquality.idr+!++rm -f *.ibc
+ test/regression002/working.idr view
@@ -0,0 +1,21 @@+module working++-- Check that using an operator beginning with "!" works++infixl 2 !!++(!!) : List a -> Nat -> Maybe a+xs !! n = index' n xs++aList : List Integer+aList = [1,2,3,4,5]++opUse : Maybe Integer+opUse = aList !! 2++opUseWithBang : Maybe Nat -> Maybe Integer+opUseWithBang mn = do aList !! !mn++doubleBang : Maybe (Maybe Nat) -> Maybe Nat+doubleBang mmn = do pure ! !mmn+
+ test/scripts/timeout view
@@ -0,0 +1,17 @@+#!/usr/bin/env perl++use strict;+use File::Basename;++sub Usage {+  my $name = basename($0);+  print STDERR "usage: $name seconds shell-command...\n";+  exit 2;+}++Usage if (scalar @ARGV) < 2;++my $timeout = shift;++alarm $timeout;+exec @ARGV;
test/sugar003/test013.idr view
@@ -1,7 +1,7 @@ module Main  forLoop : List a -> (a -> IO ()) -> IO ()-forLoop [] f = return ()+forLoop [] f = pure () forLoop (x :: xs) f = do f x                          forLoop xs f 
test/syntax001/expected view
@@ -1,5 +1,4 @@-Syntax.idr:6:7-9:1:-When checking right hand side of foo with expected type+Syntax.idr:6:7-9:1:When checking right hand side of foo with expected type         Nat  When checking an application of function Prelude.Interfaces.+:@@ -7,8 +6,7 @@                 String (Type of "argh")         and                 Nat (Expected type)-SyntaxTest.idr:5:7-6:1:-When checking right hand side of foo with expected type+SyntaxTest.idr:5:7-6:1:When checking right hand side of foo with expected type         Nat  When checking an application of function Prelude.Interfaces.+:
test/totality001/expected view
@@ -1,6 +1,3 @@-test010.idr:15:1:-Main.foo is possibly not total due to: Main.MkBad-test010a.idr:9:1:-main.bar is possibly not total due to: main.MkBad-test010b.idr:9:1:-main.bar is possibly not total due to: main.MkBad+test010.idr:15:1:Main.foo is possibly not total due to: Main.MkBad+test010a.idr:9:1:main.bar is possibly not total due to: main.MkBad+test010b.idr:9:1:main.bar is possibly not total due to: main.MkBad
test/totality002/expected view
@@ -2,5 +2,4 @@ This style of tactic proof is deprecated. See %runElab for the replacement. test017a.idr:7:1: scg.vtrans is possibly not total due to recursive path scg.vtrans --> scg.vtrans-test017b.idr:4:1:-foo.foo is possibly not total due to recursive path foo.foo+test017b.idr:4:1:foo.foo is possibly not total due to recursive path foo.foo
test/totality004/expected view
@@ -1,5 +1,4 @@ [1, 2, 2, 4, 3, 6, 4, 8, 5, 10] totality004a.idr:13:1: Main.process is possibly not total due to recursive path Main.process --> Main.process --> Main.process-totality004a.idr:24:1:-Main.main is possibly not total due to: Main.process+totality004a.idr:24:1:Main.main is possibly not total due to: Main.process
test/totality006/expected view
@@ -1,5 +1,4 @@-totality006.idr:8:1:-Main.prf is not total as there are missing cases+totality006.idr:8:1:Main.prf is not total as there are missing cases totality006a.idr:11:6:prf' (S _) (S _) Oh is a valid case totality006b.idr:10:1: totality006b.blargh is not total as there are missing cases
+ test/totality007/expected.msys view
@@ -0,0 +1,5 @@+Entering directory `.\src'+Totality.idr:4:1:+Totality.foo is not total as there are missing cases+Totality.idr:4:1:Could not build: Totality.foo is not total as there are missing cases+Leaving directory `.\src'
test/totality008/expected view
@@ -1,2 +1,1 @@-totality008.idr:7:1:-Main.ElimT is possibly not total due to: Main.C2+totality008.idr:7:1:Main.ElimT is possibly not total due to: Main.C2
test/totality010/expected view
@@ -1,4 +1,2 @@-totality010.idr:27:1:-Main.evenNotS is not total as there are missing cases-totality010.idr:30:1:-Main.bad is possibly not total due to: Main.evenNotS+totality010.idr:27:1:Main.evenNotS is not total as there are missing cases+totality010.idr:30:1:Main.bad is possibly not total due to: Main.evenNotS
test/totality015/expected view
@@ -1,6 +1,4 @@ totality015a.idr:52:3: Main.quiz is possibly not total due to recursive path Main.quiz --> Main.quiz-totality015a.idr:42:3:-Main.correct is possibly not total due to: Main.quiz-totality015a.idr:47:3:-Main.wrong is possibly not total due to: Main.quiz+totality015a.idr:42:3:Main.correct is possibly not total due to: Main.quiz+totality015a.idr:47:3:Main.wrong is possibly not total due to: Main.quiz
+ test/totality016/expected view
@@ -0,0 +1,9 @@+totality016.idr:15:1:Main.f1 is not total as there are missing cases+totality016.idr:19:1:Main.f2 is not total as there are missing cases+totality016.idr:23:1:Main.f3 is not total as there are missing cases+totality016.idr:27:1:Main.g1 is not total as there are missing cases+totality016.idr:31:1:Main.g2 is not total as there are missing cases+totality016.idr:35:1:Main.h1 is not total as there are missing cases+totality016.idr:39:1:Main.h2 is not total as there are missing cases+totality016.idr:43:1:Main.h3 is not total as there are missing cases+totality016.idr:47:1:Main.h4 is not total as there are missing cases
+ test/totality016/run view
@@ -0,0 +1,3 @@+#!/usr/bin/env bash+${IDRIS:-idris} $@ totality016.idr --check+rm -f *.ibc
+ test/totality016/totality016.idr view
@@ -0,0 +1,48 @@+%default total++data TS : Type where+  T1 : TS+  T2 : TS+  T3 : TS++data TP : Type where+  MkTP : TS -> TS -> TP++data TP2 : Type where+  MkTP2 : (TS, TS) -> TP2++f1 : TP -> Bool+f1 (MkTP T1 x) = True+f1 (MkTP x T1) = True++f2 : (TP, TS) -> Bool+f2 (MkTP T1 x, _) = True+f2 (MkTP x T1, _) = True++f3 : ((TP, TS), TS) -> Bool+f3 ((MkTP T1 x, _), _) = True+f3 ((MkTP x T1, _), _) = True++g1 : TS -> TS -> Bool+g1 T1 x = True+g1 x T1 = True++g2 : (TS, TS) -> Bool+g2 (T1, x) = True+g2 (y, T1) = True++h1 : Bool -> Bool -> Bool+h1 True x = True+h1 x True = True++h2 : (Bool, Bool) -> Bool+h2 (True, x) = True+h2 (y, True) = True++h3 : TP2 -> Bool+h3 (MkTP2 (T1, x)) = True+h3 (MkTP2 (x, T1)) = True++h4 : (TP2, TS) -> TS -> Bool+h4 (MkTP2 (T1, x), _) _ = True+h4 (MkTP2 (x, T1), _) _ = True
+ test/totality017/expected view
@@ -0,0 +1,6 @@+totality017.idr:19:1:Main.g1 is not total as there are missing cases+totality017.idr:25:1:Main.g2 is not total as there are missing cases+totality017.idr:31:1:Main.g3 is not total as there are missing cases+totality017.idr:37:1:Main.g4 is not total as there are missing cases+totality017.idr:42:1:Main.f' is not total as there are missing cases+totality017.idr:47:1:Main.f is not total as there are missing cases
+ test/totality017/run view
@@ -0,0 +1,3 @@+#!/usr/bin/env bash+${IDRIS:-idris} $@ totality017.idr --check+rm -f *.ibc
+ test/totality017/totality017.idr view
@@ -0,0 +1,49 @@+%default total++data PP : Type where+  MkPP : Int -> PP++data TT' : Nat -> Type where+  T1 : TT' 0+  T2 : (n : Nat) -> TT' (S n)++data TT'' : Int -> Type where+  T1' : TT'' 0+  T2' : (n : Int) -> TT'' (n + 1)++data TTPP : Type where+  MkTTPP : PP -> PP -> TTPP+++g1 : TT' n -> TT' n -> Bool+g1 T1 T1 = True+g1 (T2 Z) (T2 Z) = True+g1 (T2 (S Z)) (T2 (S Z)) = True+g1 (T2 (S (S Z))) (T2 (S (S Z))) = True++g2 : TT'' n -> TT'' n -> Bool+g2 T1' T1' = True+g2 (T2' 0) (T2' 0) = True+g2 (T2' 1) (T2' 1) = True+g2 (T2' 2) (T2' 2) = True++g3 : TT'' n -> Bool+g3 T1' = True+g3 (T2' 0) = True+g3 (T2' 1) = True+g3 (T2' 2) = True++g4 : TTPP -> Bool+g4 (MkTTPP (MkPP 0) (MkPP 0)) = True+g4 (MkTTPP (MkPP 1) (MkPP 1)) = True+g4 (MkTTPP (MkPP 2) (MkPP n)) = True+    +f' : Int -> Bool+f' 0 = True+f' 1 = True+f' 2 = True++f : PP -> Bool+f (MkPP 0) = True+f (MkPP 1) = True+f (MkPP 2) = True
test/unique001/expected view
@@ -2,20 +2,3 @@ 19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,END 38,36,34,32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0,END 38,36,34,32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0,END-unique001a.idr:33:11:Type mismatch between-        Int -> String-and-        UniqueType (Int -> String)-unique001a.idr:44:12:Type mismatch between-        Int -> String-and-        UniqueType (Int -> String)-unique001a.idr:55:12:Type mismatch between-        UniqueType (Int -> String)-and-        Int -> String-unique001b.idr:16:7:Borrowed name xs must not be used on RHS-unique001c.idr:46:6:Unique name f is used more than once-unique001d.idr:3:7:Borrowed name x must not be used on RHS-unique001e.idr:3:10:-Constructor Main.Nil has a UniqueType, but the data type does not
test/unique001/run view
@@ -1,9 +1,6 @@ #!/usr/bin/env bash+ ${IDRIS:-idris} $@ --nocolour unique001.idr -o unique001 ./unique001-${IDRIS:-idris} $@ --nocolour unique001a.idr --check-${IDRIS:-idris} $@ --nocolour unique001b.idr --check-${IDRIS:-idris} $@ --nocolour unique001c.idr --check-${IDRIS:-idris} $@ --nocolour unique001d.idr --check-${IDRIS:-idris} $@ --nocolour unique001e.idr --check+ rm -f unique001 *.ibc
− test/unique001/unique001a.idr
@@ -1,62 +0,0 @@-module Main--data UList : Type -> UniqueType where-     Nil   : UList a-     (::)  : a -> UList a -> UList a--umap : (a -> b) -> UList a -> UList b-umap f [] = []-umap f (x :: xs) = f x :: umap f xs--free : {a : UniqueType} -> a -> String-free xs = ""--showU : Show a => Borrowed (UList a) -> String-showU [] = "END"-showU (x :: xs) = show x ++ "," ++ showU xs--mkUList : Nat -> UList Int-mkUList Z = []-mkUList (S k) = cast k :: mkUList k--showIt : UList Int -> Int -> String-showIt xs x = let xs' = umap (*2) xs in ""--printThings : (Int -> String) -> IO ()-printThings f = do putStrLn (f 10)-                   putStrLn (f 20)--double : Int -> Int-double x = x * 2--showStuff : UList Int -> IO ()-showStuff xs = do-          putStrLn (showU xs)-          putStrLn (showU xs)-          -- xsFn gets a unique type since we're in a unique context-          -- now, but function built has a non-unique type-          (\xsFn : Int -> String =>-                   do putStrLn "Hello"-                      putStrLn (xsFn 42))-                (\dummy => showU (umap double xs))--showStuff' : UList Int -> IO ()-showStuff' xs = do-          putStrLn (showU xs)-          putStrLn (showU xs)-          -- xsFn gets a unique type since we're in a unique context-          -- now, but function built has a non-unique type-          let xsFn = \dummy : Int => showU (umap double xs)-          putStrLn "Hello"-          putStrLn (xsFn 42)-          putStrLn (xsFn 42)--showThings : UList Int -> IO ()-showThings xs = do-          putStrLn (showU xs)-          putStrLn (showU xs)-          -- showIt has a unique type, printThings wants a non-unique-          -- type-          printThings (showIt xs)--
− test/unique001/unique001b.idr
@@ -1,30 +0,0 @@-module Main--data UList : Type -> UniqueType where-     Nil   : UList a-     (::)  : a -> UList a -> UList a--umap : (a -> b) -> UList a -> UList b-umap f [] = []-umap f (x :: xs) = f x :: umap f xs--free : {a : UniqueType} -> a -> String-free xs = ""--showU : Show a => Borrowed (UList a) -> String-showU [] = "END"-showU (x :: xs) = show x ++ "," ++ free xs--mkUList : Nat -> UList Int-mkUList Z = []-mkUList (S k) = cast k :: mkUList k--showStuff : UList Int -> IO ()-showStuff xs = do-          putStrLn (showU xs)-          let xs' = umap (*2) xs-          putStrLn (showU xs')--main : IO ()-main = showStuff (mkUList 20)-
− test/unique001/unique001c.idr
@@ -1,46 +0,0 @@--data UList : Type -> UniqueType where-     UNil : UList a-     UCons : {a : Type} -> a -> UList a -> UList a--uapp : UList a -> UList a -> UList a-uapp UNil xs = xs-uapp (UCons x xs) ys = UCons x (UCons x (uapp xs ys))--data UTree : UniqueType where-     ULeaf : UTree-     UNode : UTree -> Int -> UTree -> UTree--dup : UTree -> UPair UTree UTree-dup ULeaf = (ULeaf, ULeaf)-dup (UNode l y r) = let (l1, l2) = dup l-                        (r1, r2) = dup r in-                        (UNode l1 y r1, UNode l2 y r2)--data Tree : Type where-     Leaf : Tree-     Node : Tree -> Int -> Tree -> Tree--share : UTree -> Tree-share ULeaf = Leaf-share (UNode x y z) = Node (share x) y (share z)--interface UFunctor (f : Type -> AnyType) where-    fmap : (a -> b) -> f a -> f b--implementation UFunctor List where-    fmap f [] = []-    fmap f (x :: xs) = f x :: fmap f xs--implementation UFunctor UList where-    fmap f UNil = UNil-    fmap f (UCons x xs) = UCons (f x) (fmap f xs)--uconst : {a : AnyType} -> a -> b -> a-uconst x y = x--data MPair : AnyType -> AnyType -> AnyType where-     MkMPair : {a, b : Type*} -> a -> b -> MPair a b--ndup : {a : UniqueType} -> a -> UPair a a-ndup {a} x = (\f : Int -> a => MkUPair (f 0) (f 1)) (uconst x)
− test/unique001/unique001d.idr
@@ -1,3 +0,0 @@--steal : {a : UniqueType} -> Borrowed a -> a-steal (Read x) = x
− test/unique001/unique001e.idr
@@ -1,4 +0,0 @@--data BadList : UniqueType -> Type where-     Nil : {a : UniqueType} -> BadList a-     (::) : {a : UniqueType} -> a -> BadList a -> BadList a
− test/unique002/expected
@@ -1,5 +0,0 @@-unique002.idr:15:5:Unique name xs is used more than once-unique002a.idr:15:5:Type mismatch between-        Int -> String-and-        UniqueType (Int -> String)
− test/unique002/run
@@ -1,4 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour unique002.idr --check-${IDRIS:-idris} $@ --nocolour unique002a.idr --check-rm -f *.ibc
− test/unique002/unique002.idr
@@ -1,20 +0,0 @@-data UList : Type -> UniqueType where-     Nil   : UList a-     (::)  : a -> UList a -> UList a--free : {a : UniqueType} -> a -> String-free xs = ""--showU : Show a => Borrowed (UList a) -> String-showU xs = "[" ++ showU' xs ++ "]" where-    showU' : Borrowed (UList a) -> String-    showU' [] = ""-    showU' (x :: xs) = show x ++ ", " ++ showU xs--foo : UList Int -> IO ()-foo xs = do -- let f = \x : Int => showU xs-            putStrLn $ free xs-            putStrLn $ f 42 xs-            return ()-    where f : Int -> Borrowed (UList Int) -> String-          f x xs = showU xs
− test/unique002/unique002a.idr
@@ -1,18 +0,0 @@-data UList : Type -> UniqueType where-     Nil   : UList a-     (::)  : a -> UList a -> UList a--free : {a : UniqueType} -> a -> String-free xs = ""--showU : Show a => Borrowed (UList a) -> String-showU xs = "[" ++ showU' xs ++ "]" where-    showU' : Borrowed (UList a) -> String-    showU' [] = ""-    showU' (x :: xs) = show x ++ ", " ++ showU xs--foo : UList Int -> IO ()-foo xs = do let f = \x : Int => showU xs-            putStrLn $ free xs-            putStrLn $ f 42-            return ()
− test/unique003/expected
@@ -1,4 +0,0 @@-unique003.idr:18:5:Type mismatch between-        Int -> String-and-        UniqueType (Int -> String)
− test/unique003/run
@@ -1,3 +0,0 @@-#!/usr/bin/env bash-${IDRIS:-idris} $@ --nocolour unique003.idr --check-rm -f *.ibc
− test/unique003/unique003.idr
@@ -1,22 +0,0 @@-module Main--data UList : Type -> UniqueType where-     Nil   : UList a-     (::)  : a -> UList a -> UList a--showU : Show a => Borrowed (UList a) -> String-showU xs = "[" ++ showU' xs ++ "]" where-  showU' : Borrowed (UList a) -> String-  showU' [] = ""-  showU' [x] = show x-  showU' (x :: xs) = show x ++ ", " ++ showU' xs--free : {a : UniqueType} -> a -> String-free xs = ""--foo : UList Int -> IO ()-foo xs = do let f = \x : Int => showU xs -- can't build this in unique context-            putStrLn (f 10) -            putStrLn $ free xs-            putStrLn (f 10) -            return ()
+ test/unique004/expected view
@@ -0,0 +1,26 @@+unique001a.idr:33:11:Type mismatch between+        Int -> String+and+        UniqueType (Int -> String)+unique001a.idr:44:12:Type mismatch between+        Int -> String+and+        UniqueType (Int -> String)+unique001a.idr:55:12:Type mismatch between+        UniqueType (Int -> String)+and+        Int -> String+unique001b.idr:16:7:Borrowed name xs must not be used on RHS+unique001c.idr:46:6:Unique name f is used more than once+unique001d.idr:3:7:Borrowed name x must not be used on RHS+unique001e.idr:3:10:+Constructor Main.Nil has a UniqueType, but the data type does not+unique002.idr:15:5:Unique name xs is used more than once+unique002a.idr:15:5:Type mismatch between+        Int -> String+and+        UniqueType (Int -> String)+unique003.idr:18:5:Type mismatch between+        Int -> String+and+        UniqueType (Int -> String)
+ test/unique004/run view
@@ -0,0 +1,14 @@+#!/usr/bin/env bash++${IDRIS:-idris} --nobanner --nocolour --quiet <<!+:load unique001a.idr+:load unique001b.idr+:load unique001c.idr+:load unique001d.idr+:load unique001e.idr+:load unique002.idr+:load unique002a.idr+:load unique003.idr+!++rm -f *.ibc
+ test/unique004/unique001a.idr view
@@ -0,0 +1,62 @@+module Main++data UList : Type -> UniqueType where+     Nil   : UList a+     (::)  : a -> UList a -> UList a++umap : (a -> b) -> UList a -> UList b+umap f [] = []+umap f (x :: xs) = f x :: umap f xs++free : {a : UniqueType} -> a -> String+free xs = ""++showU : Show a => Borrowed (UList a) -> String+showU [] = "END"+showU (x :: xs) = show x ++ "," ++ showU xs++mkUList : Nat -> UList Int+mkUList Z = []+mkUList (S k) = cast k :: mkUList k++showIt : UList Int -> Int -> String+showIt xs x = let xs' = umap (*2) xs in ""++printThings : (Int -> String) -> IO ()+printThings f = do putStrLn (f 10)+                   putStrLn (f 20)++double : Int -> Int+double x = x * 2++showStuff : UList Int -> IO ()+showStuff xs = do+          putStrLn (showU xs)+          putStrLn (showU xs)+          -- xsFn gets a unique type since we're in a unique context+          -- now, but function built has a non-unique type+          (\xsFn : Int -> String =>+                   do putStrLn "Hello"+                      putStrLn (xsFn 42))+                (\dummy => showU (umap double xs))++showStuff' : UList Int -> IO ()+showStuff' xs = do+          putStrLn (showU xs)+          putStrLn (showU xs)+          -- xsFn gets a unique type since we're in a unique context+          -- now, but function built has a non-unique type+          let xsFn = \dummy : Int => showU (umap double xs)+          putStrLn "Hello"+          putStrLn (xsFn 42)+          putStrLn (xsFn 42)++showThings : UList Int -> IO ()+showThings xs = do+          putStrLn (showU xs)+          putStrLn (showU xs)+          -- showIt has a unique type, printThings wants a non-unique+          -- type+          printThings (showIt xs)++
+ test/unique004/unique001b.idr view
@@ -0,0 +1,30 @@+module Main++data UList : Type -> UniqueType where+     Nil   : UList a+     (::)  : a -> UList a -> UList a++umap : (a -> b) -> UList a -> UList b+umap f [] = []+umap f (x :: xs) = f x :: umap f xs++free : {a : UniqueType} -> a -> String+free xs = ""++showU : Show a => Borrowed (UList a) -> String+showU [] = "END"+showU (x :: xs) = show x ++ "," ++ free xs++mkUList : Nat -> UList Int+mkUList Z = []+mkUList (S k) = cast k :: mkUList k++showStuff : UList Int -> IO ()+showStuff xs = do+          putStrLn (showU xs)+          let xs' = umap (*2) xs+          putStrLn (showU xs')++main : IO ()+main = showStuff (mkUList 20)+
+ test/unique004/unique001c.idr view
@@ -0,0 +1,46 @@++data UList : Type -> UniqueType where+     UNil : UList a+     UCons : {a : Type} -> a -> UList a -> UList a++uapp : UList a -> UList a -> UList a+uapp UNil xs = xs+uapp (UCons x xs) ys = UCons x (UCons x (uapp xs ys))++data UTree : UniqueType where+     ULeaf : UTree+     UNode : UTree -> Int -> UTree -> UTree++dup : UTree -> UPair UTree UTree+dup ULeaf = (ULeaf, ULeaf)+dup (UNode l y r) = let (l1, l2) = dup l+                        (r1, r2) = dup r in+                        (UNode l1 y r1, UNode l2 y r2)++data Tree : Type where+     Leaf : Tree+     Node : Tree -> Int -> Tree -> Tree++share : UTree -> Tree+share ULeaf = Leaf+share (UNode x y z) = Node (share x) y (share z)++interface UFunctor (f : Type -> AnyType) where+    fmap : (a -> b) -> f a -> f b++implementation UFunctor List where+    fmap f [] = []+    fmap f (x :: xs) = f x :: fmap f xs++implementation UFunctor UList where+    fmap f UNil = UNil+    fmap f (UCons x xs) = UCons (f x) (fmap f xs)++uconst : {a : AnyType} -> a -> b -> a+uconst x y = x++data MPair : AnyType -> AnyType -> AnyType where+     MkMPair : {a, b : Type*} -> a -> b -> MPair a b++ndup : {a : UniqueType} -> a -> UPair a a+ndup {a} x = (\f : Int -> a => MkUPair (f 0) (f 1)) (uconst x)
+ test/unique004/unique001d.idr view
@@ -0,0 +1,3 @@++steal : {a : UniqueType} -> Borrowed a -> a+steal (Read x) = x
+ test/unique004/unique001e.idr view
@@ -0,0 +1,4 @@++data BadList : UniqueType -> Type where+     Nil : {a : UniqueType} -> BadList a+     (::) : {a : UniqueType} -> a -> BadList a -> BadList a
+ test/unique004/unique002.idr view
@@ -0,0 +1,20 @@+data UList : Type -> UniqueType where+     Nil   : UList a+     (::)  : a -> UList a -> UList a++free : {a : UniqueType} -> a -> String+free xs = ""++showU : Show a => Borrowed (UList a) -> String+showU xs = "[" ++ showU' xs ++ "]" where+    showU' : Borrowed (UList a) -> String+    showU' [] = ""+    showU' (x :: xs) = show x ++ ", " ++ showU xs++foo : UList Int -> IO ()+foo xs = do -- let f = \x : Int => showU xs+            putStrLn $ free xs+            putStrLn $ f 42 xs+            pure ()+    where f : Int -> Borrowed (UList Int) -> String+          f x xs = showU xs
+ test/unique004/unique002a.idr view
@@ -0,0 +1,18 @@+data UList : Type -> UniqueType where+     Nil   : UList a+     (::)  : a -> UList a -> UList a++free : {a : UniqueType} -> a -> String+free xs = ""++showU : Show a => Borrowed (UList a) -> String+showU xs = "[" ++ showU' xs ++ "]" where+    showU' : Borrowed (UList a) -> String+    showU' [] = ""+    showU' (x :: xs) = show x ++ ", " ++ showU xs++foo : UList Int -> IO ()+foo xs = do let f = \x : Int => showU xs+            putStrLn $ free xs+            putStrLn $ f 42+            pure ()
+ test/unique004/unique003.idr view
@@ -0,0 +1,22 @@+module Main++data UList : Type -> UniqueType where+     Nil   : UList a+     (::)  : a -> UList a -> UList a++showU : Show a => Borrowed (UList a) -> String+showU xs = "[" ++ showU' xs ++ "]" where+  showU' : Borrowed (UList a) -> String+  showU' [] = ""+  showU' [x] = show x+  showU' (x :: xs) = show x ++ ", " ++ showU' xs++free : {a : UniqueType} -> a -> String+free xs = ""++foo : UList Int -> IO ()+foo xs = do let f = \x : Int => showU xs -- can't build this in unique context+            putStrLn (f 10) +            putStrLn $ free xs+            putStrLn (f 10) +            pure ()
+ win-release.sh view
@@ -0,0 +1,2 @@++IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make