packages feed

mikrokosmos 0.1.0 → 0.2.0

raw patch · 7 files changed

+354/−231 lines, 7 files

Files

+ Interpreter.hs view
@@ -0,0 +1,197 @@+{-|+Module: Interpreter+Description: Internal logic of the interpreter+License: GPL-3++This module contains auxiliary logic, types and representations of+the internal state of the interpreter.+-}+module Interpreter+  ( Context+  , emptyContext+  , InterpreterOptions (InterpreterOptions)+  , defaultOptions+  , changeVerbose+  , changeColor+  , getVerbose+  , getColor+  , InterpreterAction (..)+  , interpreteractionParser+  , act+  , multipleAct+  , Action (..)+  , actionParser+  )+where++import           Control.Applicative           ((<$>), (<*>))+import           Control.Monad.State.Lazy      +import           Text.ParserCombinators.Parsec hiding (State)+import           Data.Char+import           Data.List+import           MultiBimap+import           NamedLambda+import           Format+import           Lambda++-- | A context is an application between expressions and the names+-- they may have.+type Context  = MultiBimap Exp String++-- | Empty context without any bindings+emptyContext :: Context+emptyContext = MultiBimap.empty+++-- Interpreter options+-- | Configuration options for the interpreter. They can be changed dinamically.+data InterpreterOptions = InterpreterOptions+  { verbose :: Bool -- ^ true to produce verbose output+  , color :: Bool   -- ^ true to color the output+  }++-- | Default configuration options for the interpreter.+defaultOptions :: InterpreterOptions+defaultOptions = InterpreterOptions+  { verbose = False+  , color   = True+  }++-- | Gets the verbose configuration+getVerbose :: InterpreterOptions -> Bool+getVerbose = verbose++-- | Gets the color configuration+getColor :: InterpreterOptions -> Bool+getColor = color++-- | Sets the verbose configuration on/off.+changeVerbose :: InterpreterOptions -> InterpreterOptions+changeVerbose options = options {verbose = not $ verbose options}++-- | Sets the color configuration on/off+changeColor :: InterpreterOptions -> InterpreterOptions+changeColor options = options {color = not $ color options}++++++-- | Interpreter action. It can be a language action (binding and evaluation)+-- or an interpreter specific one, such as "quit". +data InterpreterAction = Interpret Action -- ^ Language action+                       | EmptyLine        -- ^ Empty line, it will be ignored+                       | Error            -- ^ Error on the interpreter+                       | Quit             -- ^ Close the interpreter+                       | Load String      -- ^ Load the given file+                       | SetVerbose       -- ^ Changes verbosity+                       | SetColors        -- ^ Changes colors+                       | Help             -- ^ Shows help++-- | Language action. The language has a number of possible valid statements;+-- all on the following possible forms.+data Action = Bind (String, NamedLambda)     -- ^ bind a name to an expression+            | EvalBind (String, NamedLambda) -- ^ bind a name to an expression and simplify it+            | Execute NamedLambda            -- ^ execute an expression+            | Comment                        -- ^ comment+++-- | Executes a language action. Given a context and an action, returns+-- the new context after the action and a text output.+act :: Action -> State Context [String]+act Comment = return [""]+act (Bind (s,le)) =+  do modify (\ctx -> MultiBimap.insert (toBruijn ctx le) s ctx)+     return [""]+act (EvalBind (s,le)) =+  do modify (\ctx -> MultiBimap.insert (simplifyAll $ toBruijn ctx le) s ctx)+     return [""]+act (Execute le) =+  do context <- get+     return [unlines $+             [ show le ] +++             [ unlines $ map showReduction $ simplifySteps $ toBruijn context le ] +++             [ showCompleteExp context $ simplifyAll $ toBruijn context le ]+            ]+++-- TODO: Use Text instead of String for efficiency+-- | Executes multiple actions. Given a context and a set of actions, returns+-- the new context after the sequence of actions and a text output.+multipleAct :: [Action] -> State Context [String]+multipleAct actions = concat <$> mapM act actions++++-- | Shows an expression and the name that is bound to the expression+-- in the current context+showCompleteExp :: Context -> Exp -> String+showCompleteExp context expr = case getExpressionName context expr of+  Nothing      -> show (nameExp expr)+  Just expName -> show (nameExp expr) ++ formatName ++ " ⇒ " ++ expName ++ end+++-- | Given an expression, returns its name if it is bounded to any.+getExpressionName :: Context -> Exp -> Maybe String+getExpressionName context expr = case MultiBimap.lookup expr context of+  [] -> Nothing+  xs -> Just $ intercalate ", " xs+++++-- Parsing of interpreter command line commands.+-- | Parses an interpreter action.+interpreteractionParser :: Parser InterpreterAction+interpreteractionParser = choice+  [ try interpretParser+  , try quitParser+  , try loadParser+  , try verboseParser+  , try helpParser+  ]++-- | Parses a language action as an interpreter action.+interpretParser :: Parser InterpreterAction+interpretParser = Interpret <$> actionParser++-- | Parses a language action.+actionParser :: Parser Action+actionParser = choice+  [ try bindParser+  , try evalbindParser+  , try executeParser+  , try commentParser+  ]++-- | Parses a binding between a variable an its representation.+bindParser :: Parser Action+bindParser = fmap Bind $ (,) <$> many1 alphaNum <*> (spaces >> string "!=" >> spaces >> lambdaexp)++-- | Parses a binding and evaluation expression between a variable an its representation+evalbindParser :: Parser Action+evalbindParser = fmap EvalBind $ (,) <$> many1 alphaNum <*> (spaces >> string "=" >> spaces >> lambdaexp)++-- | Parses an expression in order to execute it.+executeParser :: Parser Action+executeParser = Execute <$> lambdaexp++-- | Parses comments.+commentParser :: Parser Action+commentParser = string "#" >> many anyChar >> return Comment++-- | Parses a "quit" command.+quitParser :: Parser InterpreterAction+quitParser = string ":quit" >> return Quit++-- | Parses a "help" command.+helpParser :: Parser InterpreterAction+helpParser = string ":help" >> return Help++-- | Parses a change in verbosity.+verboseParser :: Parser InterpreterAction+verboseParser = string ":verbose" >> return SetVerbose++-- | Parses a "load-file" command.+loadParser :: Parser InterpreterAction+loadParser = Load <$> (string ":load" >> between spaces spaces (many1 (satisfy (not . isSpace))))
Lambda.hs view
@@ -3,9 +3,12 @@ Description: DeBruijn lambda expressions. License: GPL-3 -This package deals with the parsing, reduction and printing of lambda-expressions using DeBruijn notation.+This module deals with the parsing, reduction and printing of lambda+expressions using DeBruijn notation. The interpreter uses DeBruijn+notation as an internal representation and as output format. This is because+it is easier to do beta reduction with DeBruijn indexes. -}+ module Lambda   ( Exp (Var, Lambda, App)   , simplifyAll@@ -17,9 +20,6 @@ import Format  -- DeBruijn Expressions--- The interpreter uses DeBruijn notation as an internal representation and--- as output format. It is easier to do beta reduction with DeBruijn indexes.- -- | A lambda expression using DeBruijn indexes. data Exp = Var Integer -- ^ integer indexing the variable.          | Lambda Exp  -- ^ lambda abstraction
Main.hs view
@@ -1,56 +1,21 @@ module Main where -import           Control.Applicative           ((<$>), (<*>)) import           Control.Monad.Trans-import           Data.Char-import           Data.List-import qualified Data.Map.Strict               as Map-import           Data.Maybe+import           Control.Monad.State+import           Control.Exception import           System.Environment import           System.Console.Haskeline-import           Text.ParserCombinators.Parsec+import           Text.ParserCombinators.Parsec hiding (try) import           Format-import           MultiBimap-import           NamedLambda-import           Lambda+import           Interpreter +-- | A filename is a string containing the directory path and+-- the real name of the file. type Filename = String-type Context  = MultiBimap Exp String  ----- | Translates a named variable expression into a DeBruijn one.--- Uses a dictionary of already binded numbers and variables.-tobruijn :: Map.Map String Integer -- ^ dictionary of the names of the variables used-         -> Context                -- ^ dictionary of the names already binded on the scope-         -> NamedLambda            -- ^ initial expression-         -> Exp--- Every lambda abstraction is inserted in the variable dictionary,--- and every number in the dictionary increases to reflect we are entering--- into a deeper context.-tobruijn d context (LambdaAbstraction c e) = Lambda $ tobruijn newdict context e-  where newdict = Map.insert c 1 (Map.map succ d)--- Translation of applications is trivial.-tobruijn d context (LambdaApplication f g) = App (tobruijn d context f) (tobruijn d context g)--- Every variable is checked on the variable dictionary and in the current scope.-tobruijn d context (LambdaVariable c) =-  case Map.lookup c d of-    Just n  -> Var n-    Nothing -> fromMaybe (Var 0) (MultiBimap.lookupR c context)---- | Transforms a lambda expression with named variables to a deBruijn index expression.--- Uses only the dictionary of the variables in the current context.-toBruijn :: Context     -- ^ Variable context-         -> NamedLambda  -- ^ Initial lambda expression with named variables-         -> Exp-toBruijn = tobruijn Map.empty---- -- Lambda interpreter--- The logic of the interpreter is written here. It allows to execute normal+-- The actions of the interpreter are written here. It allows to execute normal -- actions (bindings and evaluation), and interpreter specific actions, as -- "quit" or "load". @@ -59,99 +24,13 @@ main = do   args <- getArgs   case args of-    [] -> runInputT defaultSettings (outputStrLn initialText-                                  >> interpreterLoop defaultOptions emptyContext)+    [] -> runInputT defaultSettings ( outputStrLn initialText+                                      >> interpreterLoop defaultOptions emptyContext+                                    )     [filename] -> executeFile filename     _ -> putStrLn "Wrong number of arguments"  --- | Executes the commands inside a file. A .mkr file can contain a sequence of---   expressions and variable bindings, and it is interpreted sequentially.-executeFile :: Filename -- Input file-            -> IO ()-executeFile filename = do-  maybeloadfile <- loadFile filename-  case maybeloadfile of-    Nothing    -> putStrLn "Error loading file"-    Just actions -> case multipleAct emptyContext actions of-                      (_, outputs) -> mapM_ (putStr . format) outputs-                      where-                        format :: String -> String-                        format "" = ""-                        format s = (++"\n") . last . lines $ s-  ---- | Empty context without any bindings-emptyContext :: Context-emptyContext = MultiBimap.empty----- | Configuration options for the interpreter. They can be changed dinamically.-data InterpreterOptions = InterpreterOptions { verbose :: Bool -- ^ true if produces verbose output-                                             , color :: Bool   -- ^ true if colors the output-                                             }---- | Default config options-defaultOptions :: InterpreterOptions-defaultOptions = InterpreterOptions { verbose = False-                                    , color   = True-                                    }---- | Interpreter action. It can be a language action (binding and evaluation)--- or an interpreter specific one, such as "quit". -data InterpreterAction = Interpret Action -- ^ Language action-                       | EmptyLine        -- ^ Empty line, it will be ignored-                       | Error            -- ^ Error on the interpreter-                       | Quit             -- ^ Close the interpreter-                       | Load String      -- ^ Load the given file-                       | SetVerbose       -- ^ Changes verbosity-                       | SetColors        -- ^ Changes colors-                       | Help             -- ^ Shows help---- | Language action. The language has a number of possible valid statements;--- all on the following possible forms.-data Action = Bind (String, NamedLambda)     -- ^ bind a name to an expression-            | EvalBind (String, NamedLambda) -- ^ bind a name to an expression and simplify it-            | Execute NamedLambda            -- ^ execute an expression-            | Comment                        -- ^ comment----- | Executes a language action. Given a context and an action, returns--- the new context after the action and a text output.-act :: Context -> Action -> (Context, String)-act context Comment           = (context,"")-act context (Bind (s,le))     = (MultiBimap.insert (toBruijn context le) s context, "")-act context (EvalBind (s,le)) = (MultiBimap.insert (simplifyAll $ toBruijn context le) s context, "")-act context (Execute le)  = (context,-                             unlines $-                              [ show le ] ++-                              [ unlines $ map showReduction $ simplifySteps $ toBruijn context le ] ++-                              [ showCompleteExp context $ simplifyAll $ toBruijn context le ]-                            )--showCompleteExp :: Context -> Exp -> String-showCompleteExp context expr = case getExpressionName context expr of-  Nothing      -> show expr-  Just expName -> show expr ++ formatName ++ " ⇒ " ++ expName ++ end--getExpressionName :: Context -> Exp -> Maybe String-getExpressionName context expr = case MultiBimap.lookup expr context of-  [] -> Nothing-  xs -> Just $ intercalate ", " xs---- TODO: Writer monad--- TODO: Use Text instead of String for efficiency--- TODO: Lists of string are inefficient--- | Executes multiple actions. Given a context and a set of actions, returns--- the new context after the sequence of actions and a text output.-multipleAct :: Context -> [Action] -> (Context, [String])-multipleAct context = foldl (\(ccontext,text) action ->-                                (fst $ act ccontext action, text ++ [snd (act ccontext action)]))-                      (context,[])------ TODO: State Monad -- | Interpreter awaiting for an instruction. interpreterLoop :: InterpreterOptions -> Context -> InputT IO () interpreterLoop options context = do@@ -166,101 +45,80 @@   case interpreteraction of     EmptyLine -> interpreterLoop options context     Quit -> return ()-    Error -> outputStrLn "Error"+    Error -> do+      outputStr formatFormula+      outputStrLn "Unknown command"+      outputStr end+      interpreterLoop options context     SetVerbose -> do-      outputStrLn $ "verbose mode: " ++ if verbose options then "off" else "on"-      interpreterLoop (options {verbose = not $ verbose options}) context-    SetColors  -> interpreterLoop (options {color   = not $ color   options}) context+      outputStrLn $+        formatFormula +++        "verbose mode: " ++ if getVerbose options then "off" else "on" +++        end+      interpreterLoop (changeVerbose options) context+    SetColors  -> interpreterLoop (changeColor options) context     Help -> outputStr helpText >> interpreterLoop options context     Load filename -> do       maybeloadfile <- lift $ loadFile filename       case maybeloadfile of-        Nothing    -> outputStrLn "Error loading file"-        Just actions -> case multipleAct context actions of-                          (ccontext, outputs) -> do-                            outputStr formatFormula-                            outputActions options outputs-                            outputStr end+        Nothing -> do+          outputStrLn "Error loading file"+          interpreterLoop options context+        Just actions -> case runState (multipleAct actions) context of+                          (output, ccontext) -> do+                            outputActions options output                             interpreterLoop options ccontext-    Interpret action -> case act context action of-                          (ccontext, output) -> do-                            outputStr formatFormula-                            outputActions options [output]-                            outputStr end+    Interpret action -> case runState (act action) context of+                          (output, ccontext) -> do+                            outputActions options output                             interpreterLoop options ccontext +++ -- | Outputs results from actions. Given a list of options and outputs, -- formats and prints them in console. outputActions :: InterpreterOptions -> [String] -> InputT IO ()-outputActions options = mapM_ (outputStr . format)+outputActions options output = do+    outputStr formatFormula+    mapM_ (outputStr . format) output+    outputStr end   where     format :: String -> String     format "" = ""     format s-      | not (verbose options) = (++"\n") . last . lines $ s+      | not (getVerbose options) = (++"\n") . last . lines $ s       | otherwise             = s ++++-- Loading and reading files -- | Loads the given filename and returns the complete list of actions. -- Returns Nothing if there is an error reading or parsing the file. loadFile :: String -> IO (Maybe [Action]) loadFile filename = do   putStrLn filename-  input <- readFile filename-  let parsing = map (parse actionParser "") $ filter (/="") $ lines input-  let actions = map (\x -> case x of-                             Left _  -> Nothing-                             Right a -> Just a) parsing-  return $ sequence actions---- | Parses an interpreter action.-interpreteractionParser :: Parser InterpreterAction-interpreteractionParser = choice [ try interpretParser-                                 , try quitParser-                                 , try loadParser-                                 , try verboseParser-                                 , try helpParser-                                 ]---- | Parses a language action as an interpreter action.-interpretParser :: Parser InterpreterAction-interpretParser = Interpret <$> actionParser---- | Parses a language action.-actionParser :: Parser Action-actionParser = choice [ try bindParser-                      , try evalbindParser-                      , try executeParser-                      , try commentParser-                      ]---- | Parses a binding between a variable an its representation.-bindParser :: Parser Action-bindParser = fmap Bind $ (,) <$> many1 alphaNum <*> (spaces >> string "!=" >> spaces >> lambdaexp)---- | Parses a binding and evaluation expression between a variable an its representation-evalbindParser :: Parser Action-evalbindParser = fmap EvalBind $ (,) <$> many1 alphaNum <*> (spaces >> string "=" >> spaces >> lambdaexp)---- | Parses an expression in order to execute it.-executeParser :: Parser Action-executeParser = Execute <$> lambdaexp---- | Parses comments.-commentParser :: Parser Action-commentParser = string "#" >> many anyChar >> return Comment---- | Parses a "quit" command.-quitParser :: Parser InterpreterAction-quitParser = string ":quit" >> return Quit---- | Parses a "help" command.-helpParser :: Parser InterpreterAction-helpParser = string ":help" >> return Help---- | Parses a change in verbosity.-verboseParser :: Parser InterpreterAction-verboseParser = string ":verbose" >> return SetVerbose+  input <- try $ (readFile filename) :: IO (Either IOException String)+  case input of+    Left _ -> return Nothing+    Right inputs -> do+      let parsing = map (parse actionParser "") $ filter (/="") $ lines inputs+      let actions = map (\x -> case x of+                                 Left _  -> Nothing+                                 Right a -> Just a) parsing+      return $ sequence actions --- | Parses a "load-file" command.-loadParser :: Parser InterpreterAction-loadParser = Load <$> (string ":load" >> between spaces spaces (many1 (satisfy (not . isSpace))))+-- | Executes the commands inside a file. A .mkr file can contain a sequence of+--   expressions and variable bindings, and it is interpreted sequentially.+executeFile :: Filename -> IO ()+executeFile filename = do+  maybeloadfile <- loadFile filename+  case maybeloadfile of+    Nothing    -> putStrLn "Error loading file"+    Just actions -> case runState (multipleAct actions) emptyContext of+                      (outputs, _) -> mapM_ (putStr . format) outputs+                      where+                        format :: String -> String+                        format "" = ""+                        format s = (++"\n") . last . lines $ s
MultiBimap.hs view
@@ -44,9 +44,9 @@  -- | Lookup a key in the multi-bimap, returning the list of -- associated values.-lookup :: (Ord k, Ord v) => k -> MultiBimap k v -> [v]+lookup :: (Ord k) => k -> MultiBimap k v -> [v] lookup k (MkMultiBimap left _) = MM.lookup k left  -- | Lookup a right value in the multi-bimap, returning the associated key.-lookupR :: (Ord k, Ord v) => v -> MultiBimap k v -> Maybe k+lookupR :: (Ord v) => v -> MultiBimap k v -> Maybe k lookupR v (MkMultiBimap _ right) = M.lookup v right
NamedLambda.hs view
@@ -10,12 +10,21 @@ module NamedLambda   ( NamedLambda (LambdaVariable, LambdaAbstraction, LambdaApplication)   , lambdaexp+  , toBruijn+  , nameExp   ) where  import           Text.ParserCombinators.Parsec import           Control.Applicative           ((<$>), (<*>))+import qualified Data.Map.Strict               as Map+import           Lambda+import           MultiBimap+import           Data.Maybe+import           Control.Monad +type Context  = MultiBimap Exp String+ -- Parsing of Lambda Expressions. -- The user can input a lambda expression with named variables, of -- the form of "\x.x" or "(\a.(\b.a b))". The interpreter will parse@@ -76,3 +85,49 @@   show = showNamedLambda  +++-- | Translates a named variable expression into a DeBruijn one.+-- Uses a dictionary of already binded numbers and variables.+tobruijn :: Map.Map String Integer -- ^ dictionary of the names of the variables used+         -> Context                -- ^ dictionary of the names already binded on the scope+         -> NamedLambda            -- ^ initial expression+         -> Exp+-- Every lambda abstraction is inserted in the variable dictionary,+-- and every number in the dictionary increases to reflect we are entering+-- into a deeper context.+tobruijn d context (LambdaAbstraction c e) = Lambda $ tobruijn newdict context e+  where newdict = Map.insert c 1 (Map.map succ d)+-- Translation of applications is trivial.+tobruijn d context (LambdaApplication f g) = App (tobruijn d context f) (tobruijn d context g)+-- Every variable is checked on the variable dictionary and in the current scope.+tobruijn d context (LambdaVariable c) =+  case Map.lookup c d of+    Just n  -> Var n+    Nothing -> fromMaybe (Var 0) (MultiBimap.lookupR c context)++-- | Transforms a lambda expression with named variables to a deBruijn index expression.+-- Uses only the dictionary of the variables in the current context. +toBruijn :: Context     -- ^ Variable context+         -> NamedLambda -- ^ Initial lambda expression with named variables+         -> Exp+toBruijn = tobruijn Map.empty++++-- | Translates a deBruijn expression into a lambda expression+-- with named variables, given a list of used and unused variable names.+nameIndexes :: [String] -> [String] -> Exp -> NamedLambda+nameIndexes _    _   (Var 0)    = LambdaVariable "undefined"+nameIndexes used _   (Var n)    = LambdaVariable (used !! pred (fromInteger n))+nameIndexes used new (Lambda e) = LambdaAbstraction (head new) (nameIndexes (head new:used) (tail new) e)+nameIndexes used new (App f g)  = LambdaApplication (nameIndexes used new f) (nameIndexes used new g)++-- | Gives names to every variable in a deBruijn expression using+-- alphabetic order.+nameExp :: Exp -> NamedLambda+nameExp = nameIndexes [] variableNames++-- | A list of all possible variable names in lexicographical order.+variableNames :: [String]+variableNames = concatMap (`replicateM` ['a'..'z']) [1..]
README.md view
@@ -12,37 +12,48 @@  ## Installation -Mikrokosmos will be soon installable from [Hackage](http://hackage.haskell.org/). Meanwhile, you can install it -cloning the repository and using [cabal](https://www.haskell.org/cabal/):+Mikrokosmos is installable from [Hackage](http://hackage.haskell.org/); you can install it directly from `cabal`: +```+cabal update+cabal install mikrokosmos+``` +You can also install it by cloning the git repository and using [cabal](https://www.haskell.org/cabal/):+ ``` bash git clone https://github.com/M42/mikrokosmos.git cd mikrokosmos cabal install ``` +If you have `ghc` version 8 or greater you can also compile it directly using:++``` bash+git clone https://github.com/M42/mikrokosmos.git+cd mikrokosmos+ghc Main.hs+```+ ## First steps  Once installed, you can open the interpreter typing `mikrokosmos` in your terminal. It will show you a prompt where you can write lambda expressions to evaluate them: -![First steps](https://cloud.githubusercontent.com/assets/5337877/18393670/92728f10-76b6-11e6-88cc-88e7f2cb9114.png)+![First steps](https://cloud.githubusercontent.com/assets/5337877/18649151/337c6782-7ebe-11e6-9701-495c2cb40675.gif)  You can write expressions using `\var.` to denote a lambda abstraction on the `var` variable and-you can bind names to expressions using `=`. *But why am I getting this weird output?* Well, the interpreter-outputs the lambda expressions in [De Bruijn notation](https://en.wikipedia.org/wiki/De_Bruijn_notation); it is more-compact and the interpreter works internally with it. However, as you can see in the image, whenever the interpreter finds a known constant, it labels the expression with its name.+you can bind names to expressions using `=`. As you can see in the image, whenever the interpreter finds a known constant, it labels the expression with its name.  If you need help at any moment, you can type `:help` into the prompt to get a summary of the available options: -![Help screen](https://cloud.githubusercontent.com/assets/5337877/18393812/33e86b6c-76b7-11e6-818b-76b68f599a44.png)+![Help screen](https://cloud.githubusercontent.com/assets/5337877/18882511/bfc84c34-84df-11e6-8215-870b29e49b8f.gif)  ## The standard library -Mikrokosmos comes bundled with a standard library. It allows you to experiment with Church encoding of booleans,-integers and much more. You can load it with `:load std.mkr`; after that, you can use a lot of new constants:+Mikrokosmos comes bundled with a standard library in a file called `std.mkr`; if it was not the case for you, you can download the [library](https://raw.githubusercontent.com/M42/mikrokosmos/master/std.mkr) from the git repository. It allows you to experiment with [Church encoding](https://en.wikipedia.org/wiki/Church_encoding) of booleans,+integers and much more. You can load it with `:load std.mkr`, given the file is in your working directory; after that, you can use a lot of new constants: -![Standard library](https://cloud.githubusercontent.com/assets/5337877/18394001/1a238ec2-76b8-11e6-90ad-b2385ba60268.png)+![Standard library](https://cloud.githubusercontent.com/assets/5337877/18663278/1a6374e2-7f1e-11e6-99b5-279de7428a10.gif)  All this is written in lambda calculus! You can check the definitions on the `std.mkr` file. @@ -52,14 +63,16 @@ It can be activated and deactivated writing `:verbose`, and it will show you every step on the reduction of the expression, coloring the substitution at every step. -![Verbose mode](https://cloud.githubusercontent.com/assets/5337877/18394177/e4925bd4-76b8-11e6-886e-6bd33fe02e88.png)+![Verbose mode](https://cloud.githubusercontent.com/assets/5337877/18882803/060a2dec-84e1-11e6-9dfa-9c08957b559e.gif) +It uses [DeBruijn notation](https://en.wikipedia.org/wiki/De_Bruijn_notation) to show the substitutions, because this is the internal representation used by the interpreter. The term in red is being substituted by the term in yellow. + ## Advanced data structures  There are representations of structures such as linked lists or trees in the standard library.  You can use them to do a bit of your usual functional programming: -![Trees](https://cloud.githubusercontent.com/assets/5337877/18394894/5cd41d1e-76bc-11e6-9564-8817992392af.png)+![Trees](https://cloud.githubusercontent.com/assets/5337877/18883269/d7c3d616-84e2-11e6-9fc9-aa6e3df606f9.gif)  Oh! And you can insert comments with `#`, both in the interpreter and in the files the interpreter can load. 
mikrokosmos.cabal view
@@ -1,5 +1,5 @@ name:                mikrokosmos-version:             0.1.0+version:             0.2.0 synopsis:            Lambda calculus interpreter description:         A didactic untyped lambda calculus interpreter. homepage:            https://github.com/M42/mikrokosmos@@ -12,13 +12,15 @@ build-type:          Simple extra-source-files:  README.md cabal-version:       >=1.10-tested-with:         GHC == 7.8.3+tested-with:         GHC == 8.0.1 extra-source-files:  std.mkr                                            source-repository head   type:           git   location:       git://github.com/M42/mikrokosmos.git-                     +++                        executable mikrokosmos   main-is:             Main.hs   build-depends:       base >=4.7 && <5,@@ -34,9 +36,7 @@                        Lambda                        NamedLambda                        MultiBimap+                       Interpreter                           default-language:    Haskell2010   ghc-options:         -Wall---