idris-0.1.7: Main.lhs
> module Main where
> import Ivor.TT hiding (transform)
> import Ivor.Shell
> import System
> import System.Environment
> import System.Time
> import System.Locale
> import System.IO
> import System.Console.Readline
> import Data.Typeable
> import Data.Binary
> import Char
> import Control.Monad
> import Control.Exception
> import List
> import Maybe
> import Debug.Trace
> import Distribution.Version
> import Prelude hiding (catch)
> import Idris.AbsSyntax
> import Idris.MakeTerm
> import Idris.Lib
> import Idris.Parser
> import Idris.Latex
> import Idris.Compiler
> import Idris.Prover
> import Idris.ConTrans
> import Idris.Fontlock
> import Idris.Serialise
> import Idris.RunIO
> import Idris.PartialEval
> import Paths_idris
Load things in this order:
* Introduce equality
* Load builtins (which don't rely on primitive types)
* Add primitives
* Load prelude
* Load users program
> idris_version = showV (versionBranch version)
> where
> showV [] = ""
> showV [a] = show a
> showV (x:xs) = show x ++ "." ++ showV xs
> data Args = Batch [String]
> | NoArgs
> main :: IO ()
> main = do args <- getArgs
> (infile, (batch, opts)) <- usage args
> ctxt <- ioTac $ addEquality emptyContext (name "Eq") (name "refl")
> (ctxt, defs) <- processInput ctxt (initState opts) "builtins.idr"
> ctxt <- ioTac $ prims ctxt
> (ctxt, defs) <- processInput ctxt defs "prelude.idr"
> (ctxt, defs) <- processInput ctxt defs infile
> let vars = idris_metavars defs
> when (not (null vars)) $
> do putStr "Proof obligations:\n\t"
> print (map fst vars)
> putStr "\n"
> repl defs ctxt batch
> usage opts@(('-':_):_) = do o <- mkArgs opts
> putStrLn "No input file"
> umessage
> usage [fname] = return (fname, (NoArgs, []))
> usage (fname:opts) = do o <- mkArgs opts
> return (fname, o)
> usage _ = umessage
> umessage =
> do putStrLn $ "Idris version " ++ idris_version
> putStrLn $ "--------------" ++ take (length idris_version) (repeat '-')
> putStrLn $ "Usage:"
> putStrLn $ "\tidris <source file> [options]"
> putStrLn $ "\n\tAvailable options:"
> putStrLn $ "\t\t -o <executable> Compile to an executable"
> putStrLn $ "\t\t --run Compile and run"
> putStrLn $ "\t\t --nospec Turn off specialisation and transformation rules"
> putStrLn $ "\t\t --noerasure Turn off erasure optimisations"
> putStrLn $ "\t\t --cmd <command> Run a command in batch mode"
> putStrLn $ "\t\t --dir Show support file location"
> putStrLn $ "\t\t --verbose Debugging output"
> putStrLn $ "\n"
> exitWith (ExitFailure 1)
> mkArgs xs = mkA' [] [] xs where
> mkA' [] opts [] = return (NoArgs, opts)
> mkA' args opts [] = return (Batch (reverse args), opts)
> mkA' args opts ("-o":output:xs)
> = mkA' ((":c " ++ output):args) opts xs
> mkA' args opts ("--run":xs)
> = mkA' (":e":args) opts xs
> mkA' args opts ("-v":xs)
> = mkA' args (Verbose:opts) xs
> mkA' args opts ("--verbose":xs)
> = mkA' args (Verbose:opts) xs
> mkA' args opts ("--nospec":xs)
> = mkA' args (NoSpec:opts) xs
> mkA' args opts ("--noerasure":xs)
> = mkA' args (NoErasure:opts) xs
> mkA' args opts ("--cmd":b:xs)
> = mkA' (b:args) opts xs
> mkA' args opts ("--dir":xs)
> = do d <- getDataDir
> putStrLn d
> exitWith ExitSuccess
> mkA' args opts (x:xs) = do putStrLn $ "Unrecognised option " ++ x ++ "\n"
> umessage
Time functions
FIXME: These use System.Time which is deprecated. Find out what to use
these days instead...
> picosec = 1000000000000
> mins = picosec*60
> hours = mins*60
> days = hours*24
> getTime :: IO Integer
> getTime = do (TOD sec pico) <- getClockTime
> return $ sec*picosec+pico
> diffTime t1 t2 = t1-t2
> showTime t = show (t `div` picosec) ++ "." ++
> (take 6 (zeros (show (t `mod` picosec)))) ++
> " seconds"
> -- add leading zeros
> where zeros t = (take (12 - length t) (repeat '0')) ++ t
> processInput :: Context -> IdrisState -> FilePath ->
> IO (Context, IdrisState)
> processInput ctxt ist file = do
> let defs = idris_context ist
> let decls = idris_decls ist
> let opts = idris_options ist
> let fixes = idris_fixities ist
> let static = idris_static ist
> let sts = idris_static_used ist
> content <- readLibFile defaultLibPath file
> (ptree, imps) <- processImports opts (idris_imports ist) (parse content file)
> let (defsin, ops) = makeIvorFuns opts defs ptree fixes
> let static' = staticDecls defsin ++ static
> let defs' = defsin -- addPEdefs static' defsin
> let alldefs = appCtxt defs defs'
> ((ctxt, metas), fixes', sts') <-
> case (addIvor opts ist alldefs defs' ctxt ops static' sts) of
> OK x fixes' sts' -> return (x, fixes', sts')
> Err x fixes' sts' err -> do putStrLn err
> return (x, fixes', sts')
> let ist = addTransforms (IState alldefs (decls ++ ptree) metas opts ops [] newCtxt imps (mkNameMap alldefs) static' sts') ctxt
> return (ctxt, ist { idris_fixities = fixes' })
> data REPLRes = Quit | Continue | NewCtxt IdrisState Context
Command; minimal abbreviation; function to run it; description; visibility
> commands
> = [("quit", "q", quit, "Exits the top level",True),
> ("type", "t", tmtype, "Print the type of a term",True),
> ("prove", "p", prove, "Begin a proof of an undefined name",True),
> ("metavars", "m", metavars,
> "Show remaining proof obligations",True),
> ("ivor", "i", ivor, "Drop into the Ivor shell",True),
> ("compile", "c", tcomp, "Compile a definition (of type IO ()", True),
> ("execute", "e", texec, "Compile and execute 'main'", True),
> ("LATEX", "L", latex, "Render a source file as LaTeX",False),
> ("HTML","H", html, "Render a source file as html", False),
> ("normalise", "n", norm, "Normalise a term (without executing)", True),
> ("definition", "d", showdef, "Show the erased version of a function or type", True),
> ("options","o", options, "Set options", True),
> ("help", "h", help, "Show help text",True),
> ("save", "s", ssave, "Save system state",True),
> ("load", "l", sload, "Load system state",True),
> ("xdebug", "xd", debug, "Show some internal stuff", False),
> ("?", "?", help, "Show help text",True)]
> type Command = IdrisState -> Context -> [String] -> IO REPLRes
> quit, tmtype, prove, metavars, tcomp, texec :: Command
> debug, norm, help, options, showdef, html, ssave :: Command
> quit _ _ _ = do return Quit
> tmtype (IState raw _ _ _ uo _ _ _ _ _ _) ctxt tms
> = do icheckType raw uo ctxt (unwords tms)
> return Continue
> prove ist ctxt (nm:[])
> = do let raw = idris_context ist
> ctxt' <- doProof raw ctxt (idris_fixities ist) (UN nm)
> let imv = filter (\ (x,y) -> x /= toIvorName (UN nm))
> (idris_metavars ist)
> let ist' = ist { idris_metavars = imv }
> return (NewCtxt ist' ctxt')
> prove ist ctxt _ = do putStrLn "What do you want to prove?"
> return Continue
> metavars ist ctxt _
> = do let vars = idris_metavars ist
> if (null vars)
> then putStrLn "All proofs complete."
> else
> do putStr "Proof obligations:\n\t"
> print (map fst vars)
> putStr "\n"
> return Continue
> ivor ist ctxt _ = do ctxt' <- doIvor ctxt
> return (NewCtxt ist ctxt')
latex ist ctxt (nm:defs)
= do latexDump (idris_context ist) (latexDefs defs) (UN nm)
return Continue
> html ist ctxt (nm:onm:style:_)
> = do htmlise (idris_context ist) nm onm (Just style)
> return Continue
> html ist ctxt (nm:onm:_)
> = do htmlise (idris_context ist) nm onm Nothing
> return Continue
> html ist ctxt _
> = do putStrLn "Please give input and output files"
> return Continue
> ssave ist ctxt (nm:_)
> = do encodeFile nm ist
> return Continue
> ssave ist ctxt _
> = do putStrLn "Please give an output file name"
> return Continue
> sload ist ctxt (nm:_)
> = do ist' <- decodeFile nm
> return (NewCtxt ist' ctxt)
> sload ist ctxt _
> = do putStrLn "Please give an input file name"
> return Continue
> latex ist ctxt (nm:onm:_)
> = do latexise (idris_context ist) nm onm
> return Continue
> latex ist ctxt _
> = do putStrLn "Please give input and output files"
> return Continue
> debug ist ctxt []
> = do putStrLn "Fixities/transforms\n"
> print (idris_fixities ist)
> putStrLn "\nStatic args:\n"
> print (idris_static ist)
> print (idris_static_used ist)
> return Continue
> tcomp ist ctxt []
> = do putStrLn "Please give an output filename"
> return Continue
> tcomp ist ctxt (top:[])
> = do let raw = idris_context ist
> comp ist ctxt (UN top) top
> -- putStrLn $ "Output " ++ top
> return Continue
> tcomp ist ctxt (top:exec:_)
> = do comp ist ctxt (UN top) exec
> return Continue
> texec ist ctxt _
> = do time <- getTime
> res <- comp ist ctxt (UN "main") "main"
> ctime <- getTime
> let cdiff = diffTime ctime time
> when (ShowRunTime `elem` (idris_options ist))
> (putStrLn $ "Compile time: " ++ showTime cdiff ++ "\n")
> when res (do system "./main"
> return ())
> rtime <- getTime
> let rdiff = diffTime rtime ctime
> when (ShowRunTime `elem` (idris_options ist))
> (putStrLn $ "\nRun time: " ++ showTime rdiff)
> return Continue
> norm ist ctxt tms
> = do let raw = idris_context ist
> termInput False raw (idris_fixities ist) ctxt (unwords tms)
> return Continue
> options ist ctxt []
> = do putStrLn $ "Options: " ++ show (idris_options ist)
> return Continue
> options ist ctxt tms
> = do let opts = idris_options ist
> let ist' = addTransforms (ist { idris_options = processOpts opts tms }) ctxt
> return $ NewCtxt ist' ctxt
> help _ _ _
> = do putStrLn $ "\nIdris version " ++ idris_version
> putStrLn $ "----------------" ++ take (length idris_version) (repeat '-')
> putStrLn "Commands available:\n"
> putStrLn "\t<expression> Execute the given expression"
> mapM_ (\ (com, _, _, desc,vis) ->
> if vis
> then putStrLn $ "\t:" ++ com ++ (take (16-length com) (repeat ' ')) ++ desc
> else return ()) commands
> putStrLn "\nCommands may be given the shortest unambiguous abbreviation (e.g. :q, :l)\n"
> return Continue
> repl :: IdrisState -> Context -> Args -> IO ()
> repl ist ctxt (Batch []) = return ()
> repl ist@(IState raw decls metas opts fixes trans syns imps nms st stu) ctxt inp'
> = do (inp, next) <- case inp' of
> Batch (b:bs) -> return (Just b, Batch bs)
> _ -> do x <- readline ("Idris> ")
> return (x, NoArgs)
> res <- case inp of
> Nothing ->
> do putChar '\n'
> return Quit
> Just (':':command) ->
> do addHistory (':':command)
> runCommand' (words command) commands
> Just exprinput ->
> do termInput' raw fixes ctxt exprinput
> addHistory exprinput
> return Continue
> case res of
> Continue -> repl ist ctxt next
> NewCtxt ist' ctxt' -> repl ist' ctxt' next
> Quit -> return ()
> where
> runCommand (c:args) ((_, abbr, fun, _, _):xs)
> | matchesAbbrev abbr c = fun ist ctxt args
> | otherwise = runCommand (c:args) xs
> runCommand _ _ = do putStrLn "Unrecognised command"
> help ist ctxt []
> return Continue
> matchesAbbrev [] _ = True
> matchesAbbrev (a:xs) (c:cs) | a == c = matchesAbbrev xs cs
> | otherwise = False
> matchesAbbrev _ _ = False
> termInput' r f c inp = handle handler $ termInput True r f c inp
> where handler StackOverflow = putStrLn "Stack overflow"
> handler UserInterrupt = putStrLn "Interrupted"
> handler e = print e -- throwIO e
> runCommand' w c = handle handler $ runCommand w c
> where handler e = do print (e :: IOError)
> return Continue
> termInput runio raw uo ctxt tm
> = case getTerm tm of
> Right tm -> execEval runio raw ctxt (tm, viewType tm)
> Left err -> print err
> where getTerm tm = do let parsed' = parseTerm tm
> case parsed' of
> Success parsed -> do
> let itm = makeIvorTerm noImplicit defDo uo (UN "__main") raw parsed
> check ctxt itm
> Failure err f l -> ttfail err
If it is an IO type, execute it, otherwise just eval it.
> execEval :: Bool -> Ctxt IvorFun -> Context -> (Term, ViewTerm) -> IO ()
> execEval True ivs ctxt (tm, (App (Name _ io) _))
> | io == name "IO.IO" = do catch (exec ctxt tm)
> (\e -> print (e :: IOError))
> -- putStrLn $ show (whnf ctxt tm)
> execEval runio ivs ctxt (tm, _)
> = do let res = (evalnew ctxt tm)
> -- print res
> -- putStrLn (showImp True (unIvor ivs (view res)))
> putStr (showImp False (unIvor ivs (view res)))
> putStrLn $ " : " ++ showImp False (unIvor ivs (viewType res))
> icheckType :: Ctxt IvorFun -> UserOps -> Context -> String -> IO ()
> icheckType ivs uo ctxt tmin
> = case parseTerm tmin of
> Success tm ->
> do let itm = makeIvorTerm noImplicit defDo uo (UN "__main") ivs tm
> gtm <- ioTac $ check ctxt itm
> putStrLn $ showImp False (unIvor ivs (viewType gtm))
> Failure err _ _ -> putStrLn err
> processOpts :: [Opt] -> [String] -> [Opt]
> processOpts opts [] = opts
> processOpts opts (x:xs) = processOpts (processOpt opts x) xs
> processOpt opts "f-" = nub (NoErasure:opts)
> processOpt opts "r+" = nub (ShowRunTime:opts)
> processOpt opts "f+" = (nub opts) \\ [NoErasure]
> processOpt opts "r-" = (nub opts) \\ [ShowRunTime]
> processOpt opts _ = opts -- silently ignore (FIXME)
Look up the name as a pattern definition, then as an inductive, and show
the appropriate thing, after applying the relevant transformations.
> showdef ist ctxt []
> = do putStrLn "Please give a name"
> return Continue
> showdef ist ctxt (n:_)
> = do case getPatternDef ctxt (name n) of
> Right (ty, pats) -> do showPDefs n (idris_context ist) (transform ctxt [] (transforms (idris_fixities ist)) (name n) pats)
> putStrLn "Compiles as:\n"
> showPats n (idris_context ist) (transform ctxt
> (idris_transforms ist)
> (transforms (idris_fixities ist))
> (name n) pats)
> -- let Right (args, sc) = getCompiledPatternDef ctxt (name n)
> -- putStrLn "\nInternally compiled as:\n"
> -- print (args, sc)
> _ -> case getInductive ctxt (name n) of
> Right ind -> showInductive n ctxt (idris_transforms ist)
> (constructors ind)
> _ -> putStrLn $ n ++ " not defined"
> return Continue
> showPats :: String -> Ctxt IvorFun -> Patterns -> IO ()
> showPats n ivs (Patterns ps) = putStrLn $ concat (map (\x -> showp' x ++ "\n") ps)
> where showp' (PClause args _ ty)
> = n ++ " " ++ concat (map (\x -> showarg (show x)) args) ++ "= " ++ showId ty
> showarg x = if (' ' `elem` x) then "(" ++ x ++ ") " else x ++ " "
> showId res = show res -- showImp True (unIvor ivs res)
> showPDefs :: String -> Ctxt IvorFun -> Patterns -> IO ()
> showPDefs n ivs (Patterns ps) = putStrLn $ concat (map (\x -> showp' x ++ "\n") ps)
> where showp' (PClause args _ ty)
> = n ++ " " ++ concat (map (\x -> showarg (show x)) args) ++ "= " ++ showId ty
> showarg x = if (' ' `elem` x) then "(" ++ x ++ ") " else x ++ " "
> showId res = showImp False (unIvor ivs res)
> showInductive :: String -> Context -> [Transform] ->
> [(Name, ViewTerm)] -> IO ()
> showInductive n ctxt trans cons
> = do putStrLn $ n ++ " constructors:"
> putStrLn $ concat (map (\x -> " " ++ showc x ++ "\n") cons)
> where showc (n, ty) = let atys = Ivor.TT.getArgTypes ty
> args = map mkName atys
> app = apply (Name DataCon n) args in
> show (applyTransforms ctxt trans app)
> mkName (n, ty) = Name Unknown (name (showarg (useName (show n) ty)))
> useName ('_':'_':_) ty = show ty
> useName n ty = n ++ " : " ++ show ty
> showarg x = if (' ' `elem` x) then "(" ++ x ++ ")" else x
> prims c = do c <- addPrimitive c (name "Int")
> c <- addPrimitive c (name "Char")
> c <- addPrimitive c (name "Float")
> c <- addPrimitive c (name "String")
> c <- addPrimitive c (name "Lock")
> c <- addPrimitive c (name "Handle")
> c <- addPrimitive c (name "Ptr")
> c <- addBinOp c (opFn Plus) ((+)::Int->Int->Int) "Int->Int->Int"
> c <- addBinOp c (opFn Minus) ((-)::Int->Int->Int)
> "Int->Int->Int"
> c <- addBinOp c (opFn Times) ((*)::Int->Int->Int)
> "Int->Int->Int"
> c <- addBinOp c (opFn Divide) (div::Int->Int->Int)
> "Int->Int->Int"
> c <- addBinOp c (opFn Modulo) (mod::Int->Int->Int)
> "Int->Int->Int"
> c <- addBinOp c (opFn FPlus) ((+)::Double->Double->Double) "Float->Float->Float"
> c <- addBinOp c (opFn FMinus) ((-)::Double->Double->Double)
> "Float->Float->Float"
> c <- addBinOp c (opFn FTimes) ((*)::Double->Double->Double)
> "Float->Float->Float"
> c <- addBinOp c (opFn FDivide) ((/)::Double->Double->Double)
> "Float->Float->Float"
> c <- addBinOp c (opFn Concat) ((++)::String->String->String)
> "String->String->String"
> c <- addBinOp c (opFn StringGetIndex)
> ((\str i -> str!!!(i,"stringGetIndex fail"))::String->Int->Char)
> "String->Int->Char"
> c <- addBinOp c (opFn ShL) (shl::Int->Int->Int) "Int->Int->Int"
> c <- addBinOp c (opFn ShR) (shr::Int->Int->Int) "Int->Int->Int"
> c <- addExternalFn c (opFn OpEq) 2 constEq "Int->Int->Bool"
> c <- addExternalFn c (name "__charEq") 2 constEq "Char->Char->Bool"
> c <- addExternalFn c (name "__strEq") 2 constEq "String->String->Bool"
> c <- addExternalFn c (name "__strLT") 2 constLT "String->String->Bool"
> c <- addExternalFn c (opFn OpLT) 2 intlt "Int->Int->Bool"
> c <- addExternalFn c (opFn OpLEq) 2 intle "Int->Int->Bool"
> c <- addExternalFn c (opFn OpGT) 2 intgt "Int->Int->Bool"
> c <- addExternalFn c (opFn OpGEq) 2 intge "Int->Int->Bool"
> c <- addExternalFn c (opFn OpFEq) 2 constEq "Float->Float->Bool"
> c <- addExternalFn c (opFn OpFLT) 2 floatlt "Float->Float->Bool"
> c <- addExternalFn c (opFn OpFLEq) 2 floatle "Float->Float->Bool"
> c <- addExternalFn c (opFn OpFGT) 2 floatgt "Float->Float->Bool"
> c <- addExternalFn c (opFn OpFGEq) 2 floatge "Float->Float->Bool"
> c <- addExternalFn c (opFn FloatToString) 1 floatToString "Float->String"
> c <- addExternalFn c (opFn ToString) 1 intToString "Int->String"
> c <- addExternalFn c (opFn ToInt) 1 stringToInt "String->Int"
> c <- addExternalFn c (opFn StringToFloat) 1 stringToFloat "String->Float"
> c <- addExternalFn c (opFn IntToChar) 1 intToChar "Int->Char"
> c <- addExternalFn c (opFn CharToInt) 1 charToInt "Char->Int"
> c <- addExternalFn c (opFn StringLength) 1 stringLen "String->Int"
> c <- addExternalFn c (opFn StringHead) 1 stringHead "String->Char"
> c <- addExternalFn c (opFn StringTail) 1 stringTail "String->String"
> c <- addExternalFn c (opFn StringCons) 2 stringCons "Char->String->String"
> c <- addExternalFn c (opFn StringRev) 1 stringRev "String->String"
> c <- addExternalFn c (opFn StringSub) 3 stringSub "String->Int->Int->String"
> c <- addExternalFn c (opFn StringFind) 2 stringFind "String->Char->Int"
> c <- addExternalFn c (name "__Prove_Anything") 3 proveAnything
> "(A:*)->(B:*)->A->B"
> c <- addExternalFn c (name "__lazy") 1 runLazy "(A:*)A->A"
> c <- addExternalFn c (name "__effect") 1 runEffect "(A:*)A->A"
> return c
> shl :: Int -> Int -> Int
> shl x 0 = x
> shl x n = shl (x*2) (n-1)
> shr :: Int -> Int -> Int
> shr x 0 = x
> shr x n = shr (x `div` 2) (n-1)
> constEq :: [ViewTerm] -> Maybe ViewTerm
> constEq [Constant x, Constant y]
> = case cast x of
> Just x' -> if (x'==y)
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> constEq _ = Nothing
> constLT :: [ViewTerm] -> Maybe ViewTerm
> constLT [Constant x, Constant y]
> = case (cast x, cast y) :: (Maybe String, Maybe String) of
> (Just x', Just y') -> if (x'<y')
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing -- Just $ Name DataCon (name "False")
constEq [_, x, y] = if (x == y) then Just $ Name DataCon (name "True")
else Just $ Name DataCon (name "False")
> constLT _ = Nothing
> intlt :: [ViewTerm] -> Maybe ViewTerm
> intlt [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'<(y'::Int))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> intlt _ = Nothing
> intle :: [ViewTerm] -> Maybe ViewTerm
> intle [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'<=(y'::Int))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> intle _ = Nothing
> intgt :: [ViewTerm] -> Maybe ViewTerm
> intgt [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'>(y'::Int))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> intgt _ = Nothing
> intge :: [ViewTerm] -> Maybe ViewTerm
> intge [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'>=(y'::Int))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> intge _ = Nothing
> floatlt :: [ViewTerm] -> Maybe ViewTerm
> floatlt [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'<(y'::Double))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> floatlt _ = Nothing
> floatle :: [ViewTerm] -> Maybe ViewTerm
> floatle [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'<=(y'::Double))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> floatle _ = Nothing
> floatgt :: [ViewTerm] -> Maybe ViewTerm
> floatgt [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'>(y'::Double))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> floatgt _ = Nothing
> floatge :: [ViewTerm] -> Maybe ViewTerm
> floatge [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just x', Just y') -> if (x'>=(y'::Double))
> then Just $ Name DataCon (name "True")
> else Just $ Name DataCon (name "False")
> _ -> Nothing
> floatge _ = Nothing
> intToString :: [ViewTerm] -> Maybe ViewTerm
> intToString [Constant x]
> = case cast x of
> (Just s) -> Just (Constant (iToS s))
> _ -> Nothing
> where iToS :: Int -> String
> iToS x = show x
> intToString _ = Nothing
> floatToString :: [ViewTerm] -> Maybe ViewTerm
> floatToString [Constant x]
> = case cast x of
> (Just s) -> Just (Constant (fToS s))
> _ -> Nothing
> where fToS :: Double -> String
> fToS x = show x
> floatToString _ = Nothing
> stringToInt :: [ViewTerm] -> Maybe ViewTerm
> stringToInt [Constant x]
> = case cast x of
> (Just s) -> Just (Constant (sToI s))
> _ -> Nothing
> where sToI :: String -> Int
> sToI ('-':s) | all isDigit s = -(read s)
> sToI s | all isDigit s = read s
> | otherwise = 0
> stringToInt _ = Nothing
> stringToFloat :: [ViewTerm] -> Maybe ViewTerm
> stringToFloat [Constant x]
> = case cast x of
> (Just s) -> Just (Constant (sToF s))
> _ -> Nothing
> where sToF :: String -> Int
> sToF ('-':s) = -(read s)
> sToF s = read s
> stringToFloat _ = Nothing
> intToChar :: [ViewTerm] -> Maybe ViewTerm
> intToChar [Constant x] = case cast x :: Maybe Int of
> Just i -> Just (Constant (toEnum i :: Char))
> _ -> Nothing
> intToChar _ = Nothing
> charToInt :: [ViewTerm] -> Maybe ViewTerm
> charToInt [Constant x] = case cast x :: Maybe Char of
> Just i -> Just (Constant (fromEnum i :: Int))
> _ -> Nothing
> charToInt _ = Nothing
> stringLen :: [ViewTerm] -> Maybe ViewTerm
> stringLen [Constant x] = case cast x :: Maybe String of
> (Just s) -> Just (Constant (length s))
> _ -> Nothing
> stringLen _ = Nothing
> stringHead :: [ViewTerm] -> Maybe ViewTerm
> stringHead [Constant x] = case cast x :: Maybe String of
> (Just (s:ss)) -> Just (Constant s)
> _ -> Nothing
> stringHead _ = Nothing
> stringTail :: [ViewTerm] -> Maybe ViewTerm
> stringTail [Constant x] = case cast x :: Maybe String of
> (Just (s:ss)) -> Just (Constant ss)
> _ -> Nothing
> stringTail _ = Nothing
> stringCons :: [ViewTerm] -> Maybe ViewTerm
> stringCons [Constant x, Constant y]
> = case (cast x, cast y) of
> (Just s, Just ss) -> Just (Constant ((s:ss) :: String))
> _ -> Nothing
> stringCons _ = Nothing
> stringRev :: [ViewTerm] -> Maybe ViewTerm
> stringRev [Constant x] = case cast x :: Maybe String of
> Just s -> Just (Constant (reverse s))
> _ -> Nothing
> stringRev _ = Nothing
> stringSub :: [ViewTerm] -> Maybe ViewTerm
> stringSub [Constant x, Constant start, Constant len]
> = case (cast x, cast start, cast len) ::
> (Maybe String, Maybe Int, Maybe Int) of
> (Just str, Just st, Just l) ->
> Just (Constant (take l (drop st str) :: String))
> _ -> Nothing
> stringSub _ = Nothing
> stringFind :: [ViewTerm] -> Maybe ViewTerm
> stringFind [Constant x, Constant y]
> = case (cast x, cast y) :: (Maybe String, Maybe Char) of
> (Just s, Just c) ->
> case findIndex (==c) s of
> Just v -> Just (Constant v)
> Nothing -> Just (Constant ((-1) :: Int))
> _ -> Nothing
> stringFind _ = Nothing
> proveAnything :: [ViewTerm] -> Maybe ViewTerm
> proveAnything [_,_,x] = Just x
> proveAnything _ = Nothing
> runLazy :: [ViewTerm] -> Maybe ViewTerm
> runLazy [_,x] = Just x
> runLazy _ = Nothing
> runEffect :: [ViewTerm] -> Maybe ViewTerm
> runEffect [_,x] = Just x
> runEffect _ = Nothing