Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kputnam/lambad
Toy implementations of typed lambda calculi
https://github.com/kputnam/lambad
compilers lambda-calculus
Last synced: 8 days ago
JSON representation
Toy implementations of typed lambda calculi
- Host: GitHub
- URL: https://github.com/kputnam/lambad
- Owner: kputnam
- License: other
- Created: 2022-04-13T17:38:55.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-04-13T19:40:46.000Z (over 2 years ago)
- Last Synced: 2024-10-07T20:41:08.877Z (about 1 month ago)
- Topics: compilers, lambda-calculus
- Language: Haskell
- Homepage:
- Size: 163 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
## Demonstrating Lambda Calculus Reduction
http://www.itu.dk/people/sestoft/papers/sestoft-lamreduce.pdf
Reduce under λ
+------------------+-----------------------+
Strict| Y | N |
+-----+------------------+-----------------------+
| Y | Normal form | Weak normal form |
| | E ∷= λx.E , x E | E ∷= λx.e , x E |
| | | |
| | ao, no, ha, hn | bv |
+-----+------------------+-----------------------+
| N | Head normal form | Weak head normal form |
| | E ∷= λx.E , x e | E ∷= λx.e , x e |
| | | |
| | he | bn |
+-----+------------------+-----------------------+e ∷= x | λx.e | e e
* ao: `applicativeOrder`
* no: `normalOrder`
* ha: `hybridApplicative`
* hn: `hybridNormal`
* bv: `callByValue`
* he: `headSpine`
* bn: `callByName`## How to Install
$ git clone [email protected]:kputnam/lambad.git
$ cd lambad
$ cabal install --enable-tests## How to Use
There are three functions defined for use in GHCi. Both `eval` and `evalPrint`
take an reduction strategy (callByName, callByValue, normalOrder, hybridNormal,
hybridApplicative, applicativeOrder, and headSpine), an environment, and a Text
string denoting a lambda calculus expression.`eval` returns a value of type `(Either Text Expression, [Step Expression])`,
where first element is either an error message or the result of the computation
and the second element is a list of reduction steps.`evalPrint` returns a value of type `Either Text Expression` and pretty-prints
the reduction steps to the console as a side effect.`evalEach` takes only an environment and a Text string. It evaluates the
expression using each strategy and prints a table showing the number of
subexpressions evaluated and the evaluated result.#### Environments
Environments are used to resolve free variables, which otherwise are interpreted
as data constructors. Use `emptyEnv` to skip resolving free variables.You can load definitions if you like, using `evalEnv` and providing a reduction
strategy and a Text string with declarations formatted like:(declare Z (lambda f x. x))
(declare S (lambda n f x. f (n f x)))This will return an `Environment Expression` value, which can be passed to the
eval methods above.### Example
Here's an example of adding the Church-encoded numerals, 2 and 2. The
line breaks are added for readability, but they aren't required.$ ghci
> :set prompt "> "> evalEach emptyEnv
"(lambda Z S +. (+ (S (S Z)) (S (S Z))))
(lambda f x. x)
(lambda n f x. n f (f x))
(lambda m n f x. m f (n f x))"ao (284): λf x. f (f (f (f x)))
no (310): λf x. f (f (f (f x)))
ha (146): λf x. f (f (f (f x)))
hn (125): λf x. f (f (f (f x)))
bv (28): λf x. (λf x. (λf x. (λf x. x) f (f x)) f (f x)) f ((λf x. (λf x. (λf x. x) f (f x)) f (f x)) f x)
he (75): λf x. f (f ((λn f x. n f (f x)) ((λn f x. n f (f x)) (λf x. x)) f x))
bn (11): λf x. (λn f x. n f (f x)) ((λn f x. n f (f x)) (λf x. x)) f ((λn f x. n f (f x)) ((λn f x. n f (f x)) (λf x. x)) f x)> evalPrint applicativeOrder emptyEnv
"(lambda Z S +. + (S (S Z)) (S (S Z)))
(lambda f x. x)
(lambda n f x. f (n f x))
(lambda n m f x. m f (n f x))"...
=> f (f x)
>> f (f (f (f x)))
>> f
=> f
>> f (f (f x))
>> f
=> f
>> f (f x)
>> f
=> f
>> f x
>> f
=> f
>> x
=> x
=> f x
=> f (f x)
=> f (f (f x))
=> f (f (f (f x)))
=> f (f (f (f x)))
=> λx. f (f (f (f x)))
=> λf x. f (f (f (f x)))
=> λf x. f (f (f (f x)))
=> λf x. f (f (f (f x)))
276.0 stepsRight (Abstraction "f"
(Abstraction "x"
(Application
(Variable "f")
(Application
(Variable "f")
(Application
(Variable "f")
(Application
(Variable "f")
(Variable "x")))))))The result is the Church-encoded representation of 4: `λf x. f (f (f (f x)))`.
### Reading from a File
-- Reading an Expression from a file
> import Control.Applicative
> import qualified Data.Text.IO as T
> evalPrint applicativeOrder emptyEnv =<< T.readFile "example.pure"-- Reading an Environment from a file
> let myEnv = either (const emptyEnv) id
<$> evalEnv hybridNormal
<$> T.readFile "library.pure"
> flip (evalPrint hybridNormal) "id" =<< myEnv-- Doing both
> :{
do code <- T.readFile "example.pure"
env <- myEnv
evalPrint hybridNormal env code
:}