3 people like it.

# Complete lambda calculus interpreter with example of Y-combinator recursion

Calculate triangle numbers in the most inefficient way possible!

 ``` 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: ``` ``````/// Based on https://opendsa-server.cs.vt.edu/ODSA/Books/PL/html/index.html#lambda-calculus namespace LambdaCalculus open System /// A variable in a lambda expression. type Variable = string (*name*) /// Lambda expression. [] type Expr = /// E.g. "x" | Variable of Variable /// E.g. "(x y)" | Application of (Expr (*function*) * Expr (*argument*)) /// E.g. "λx.y" | Lambda of (Variable (*parameter*) * Expr (*body*)) /// Converts expression to string. member this.String = match this with | Variable name -> name | Application (func, arg) -> sprintf "(%A %A)" func arg | Lambda (param, body) -> sprintf "λ%s.%A" param body /// Converts expression to string. override this.ToString() = this.String /// Lambda expression functions. [] module Expr = /// Interop with F# quotations. module private FSharp = open Microsoft.FSharp.Quotations.Patterns /// Constructs a lambda expression from an F# quotation. let rec ofQuot = function | Var var -> Variable var.Name // bound | ValueWithName (_, _, name) -> // free Variable name | Application (func, arg) -> Application (ofQuot func, ofQuot arg) | Lambda (param, body) -> Lambda (param.Name, ofQuot body) | expr -> failwithf "Not supported: %A" expr let ofQuot = FSharp.ofQuot module private Parse = open FParsec let private parseExpr, private parseExprRef = createParserForwardedToRef() let private parseName = many1Chars (satisfy (fun c -> Char.IsLetterOrDigit(c) && (c <> 'λ'))) let private parseVariable = parseName |>> Variable let private parseApplication = pipe5 (skipChar '(') parseExpr (many1 <| skipChar ' ') parseExpr (skipChar ')') (fun _ func _ arg _ -> Application (func, arg)) let private parseLambda = pipe4 (skipAnyOf ['λ'; '^'; '\\']) parseName (skipChar '.') parseExpr (fun _ param _ body -> Lambda (param, body)) do parseExprRef := choice [ parseVariable parseApplication parseLambda ] let parse str = let parser = !parseExprRef .>> eof // force consumption of entire string match run parser str with | Success (expr, _, _) -> expr | Failure (msg, _, _) -> failwith msg let parse = Parse.parse let toString (expr : Expr) = expr.ToString() /// Indicates whether the given variable occurs within a lambda expression (either /// bound or free). let rec occurs name = function | Variable name' -> name' = name | Application (func, arg) -> occurs name func || occurs name arg | Lambda (param, body) -> (param = name) || occurs name body /// Indicates whether the given variable occurs free within a lambda expression. /// (Note that it might occur both free and bound.) let rec occursFree name = function | Variable name' -> name' = name | Application (func, arg) -> occursFree name func || occursFree name arg | Lambda (param, body) -> (param <> name) && occursFree name body /// α-conversion. let alphaConvert newName lambda = let rec convert oldName newName expr = let convert = convert oldName newName match expr with | Variable name -> assert(name <> newName) if name = oldName then Variable newName // rename variable else expr | Application (func, arg) -> Application ((convert func), (convert arg)) | Lambda (param, body) -> // inner lambda assert(param <> newName) Lambda (param, convert body) if occurs newName lambda then failwithf "New name '%s' already appears in %A" newName lambda match lambda with | Lambda (param, body) -> Lambda (newName, convert param newName body) | _ -> failwithf "α-conversion not supported for %A" lambda module Option = let defaultWith defThunk option = match option with None -> defThunk () | Some v -> v /// Replaces all occurrences of param with arg in body. let rec substitute arg param body = /// Answers the set of all variables in the given expression. let allVariables expr = let rec loop expr : seq = seq { match expr with | Variable name -> yield name | Application (func, arg) -> yield! loop func yield! loop arg | Lambda (param, body) -> yield param yield! loop body } loop expr |> Set.ofSeq let subst = substitute arg param match body with | Variable name -> if name = param then arg // replace this variable with the new expression else body // no-op | Application (func, arg) -> Application (subst func, subst arg) | Lambda (param', body') -> if param' = param then body // no-op (don't actually substitute anything) elif occursFree param' arg then // avoid variable capture let allVars = allVariables body ['a' .. 'z'] |> Seq.map (fun c -> c.ToString()) |> Seq.tryFind (fun newName -> not <| allVars.Contains(newName)) |> Option.map (fun newName -> alphaConvert newName body |> subst) |> Option.defaultWith (fun () -> failwithf "Exhausted variable names for α-conversion") else Lambda (param', subst body') // substitute new expression in lambda body /// Reduces a β-reduction expression ("β-redex"). This is /// function evaluation, which "calls" the given lambda /// with the given argument. let betaReduce = function | Application (Lambda (param, body), arg) -> substitute arg param body | expr -> failwithf "%A is not a β-redex" expr /// Evaluates the given expression lazily (normal order). /// See reduceLeftmostOutermostBetaRedex and reduceToNormalForm in /// https://opendsa-server.cs.vt.edu/ODSA/AV/PL/interpreters/lambdacalc/version1.4.used.in.book/scripts/interpreter.js let eval expr = let rec containsBetaRedex = function | Variable _ -> false | Application (Lambda (_, _), _) -> true | Application (func, arg) -> containsBetaRedex func || containsBetaRedex arg | Lambda (_, body) -> containsBetaRedex body let rec reduceLazy expr = match expr with | Variable _ -> expr | Application (Lambda (_, _), _) -> betaReduce expr | Application (func, arg) -> if containsBetaRedex func then Application (reduceLazy func, arg) elif containsBetaRedex arg then Application (func, reduceLazy arg) else expr | Lambda (param, body) -> Lambda (param, reduceLazy body) let rec loop expr = if containsBetaRedex expr then reduceLazy expr |> loop else expr loop expr [] module Lang = let True = <@@ fun x y -> x @@> |> Expr.ofQuot let False = <@@ fun x y -> y @@> |> Expr.ofQuot let If = <@@ fun b x y -> b x y @@> |> Expr.ofQuot let And = sprintf "λp.λq.((p q) %A)" False |> Expr.parse let Or = sprintf "λp.λq.((p %A) q)" True |> Expr.parse let Zero = <@@ fun f x -> x @@> |> Expr.ofQuot // same as False let One = <@@ fun f x -> f x @@> |> Expr.ofQuot let Two = <@@ fun f x -> f (f x) @@> |> Expr.ofQuot let Three = <@@ fun f x -> f (f (f x)) @@> |> Expr.ofQuot let Four = <@@ fun f x -> f (f (f (f x))) @@> |> Expr.ofQuot let Five = <@@ fun f x -> f (f (f (f (f x)))) @@> |> Expr.ofQuot let Six = <@@ fun f x -> f (f (f (f (f (f x))))) @@> |> Expr.ofQuot let Seven = <@@ fun f x -> f (f (f (f (f (f (f x)))))) @@> |> Expr.ofQuot let Eight = <@@ fun f x -> f (f (f (f (f (f (f (f x))))))) @@> |> Expr.ofQuot let Nine = <@@ fun f x -> f (f (f (f (f (f (f (f (f x)))))))) @@> |> Expr.ofQuot let Ten = <@@ fun f x -> f (f (f (f (f (f (f (f (f (f x))))))))) @@> |> Expr.ofQuot let Succ = <@@ fun n f x -> f ((n f) x) @@> |> Expr.ofQuot let Plus = <@@ fun m n f x -> (n f) ((m f) x) @@> |> Expr.ofQuot let Mult = <@@ fun m n f -> m (n f) @@> |> Expr.ofQuot /// Y-combinator for recursion let Y = "λh.(λx.(h (x x)) λx.(h (x x)))" |> Expr.parse module Program = [] let main argv = // display λ chars correctly Console.OutputEncoding <- Text.Encoding.Unicode let IsZero = sprintf "λn.((n λx.%A) %A)" False True |> Expr.parse let Pred = "λn.λf.λx.(((n λg.λh.(h (g f))) λu.x) λu.u)" |> Expr.parse let TriangleNonRecursive = sprintf "λg.λn.(((%A (%A n)) %A) ((%A n) (g (%A n))))" If IsZero Zero Plus Pred |> Expr.parse let TriangleRecursive = sprintf "(%A %A)" Y TriangleNonRecursive |> Expr.parse let expr = sprintf "(%A %A)" TriangleRecursive Four |> Expr.parse |> Expr.eval printfn "%A" expr 0 ``````
namespace System
type Variable = string

Full name: LambdaCalculus.Variable

A variable in a lambda expression.
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
Multiple items
type StructuredFormatDisplayAttribute =
inherit Attribute
new : value:string -> StructuredFormatDisplayAttribute
member Value : string

Full name: Microsoft.FSharp.Core.StructuredFormatDisplayAttribute

--------------------
new : value:string -> StructuredFormatDisplayAttribute
type Expr =
| Variable of Variable
| Application of (Expr * Expr)
| Lambda of (Variable * Expr)
override ToString : unit -> string
member String : Variable

Full name: LambdaCalculus.Expr

Lambda expression.
Multiple items
union case Expr.Variable: Variable -> Expr

E.g. "x"

--------------------
type Variable = string

Full name: LambdaCalculus.Variable

A variable in a lambda expression.
union case Expr.Application: (Expr * Expr) -> Expr

E.g. "(x y)"
union case Expr.Lambda: (Variable * Expr) -> Expr

E.g. "λx.y"
val this : Expr
Multiple items
member Expr.String : Variable

Full name: LambdaCalculus.Expr.String

Converts expression to string.

--------------------
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val name : Variable
val func : Expr
val arg : Expr
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val param : Variable
val body : Expr
override Expr.ToString : unit -> string

Full name: LambdaCalculus.Expr.ToString

Converts expression to string.
property Expr.String: Variable

Converts expression to string.
Multiple items
type CompilationRepresentationAttribute =
inherit Attribute
new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
member Flags : CompilationRepresentationFlags

Full name: Microsoft.FSharp.Core.CompilationRepresentationAttribute

--------------------
new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
type CompilationRepresentationFlags =
| None = 0
| Static = 1
| Instance = 2
| ModuleSuffix = 4
| UseNullAsTrueValue = 8
| Event = 16

Full name: Microsoft.FSharp.Core.CompilationRepresentationFlags
CompilationRepresentationFlags.ModuleSuffix: CompilationRepresentationFlags = 4
namespace Microsoft.FSharp
namespace Microsoft
namespace Microsoft.FSharp.Quotations
module Patterns

from Microsoft.FSharp.Quotations
val private ofQuot : _arg1:Quotations.Expr -> Expr

Full name: LambdaCalculus.ExprModule.FSharp.ofQuot

Constructs a lambda expression from an F# quotation.
active recognizer Var: Quotations.Expr -> Quotations.Var option

Full name: Microsoft.FSharp.Quotations.Patterns.( |Var|_| )
val var : Quotations.Var
property Quotations.Var.Name: string
active recognizer ValueWithName: Quotations.Expr -> (obj * Type * string) option

Full name: Microsoft.FSharp.Quotations.Patterns.( |ValueWithName|_| )
val name : string
Multiple items
union case Expr.Application: (Expr * Expr) -> Expr

E.g. "(x y)"

--------------------
active recognizer Application: Quotations.Expr -> (Quotations.Expr * Quotations.Expr) option

Full name: Microsoft.FSharp.Quotations.Patterns.( |Application|_| )
val func : Quotations.Expr
val arg : Quotations.Expr
Multiple items
union case Expr.Lambda: (Variable * Expr) -> Expr

E.g. "λx.y"

--------------------
active recognizer Lambda: Quotations.Expr -> (Quotations.Var * Quotations.Expr) option

Full name: Microsoft.FSharp.Quotations.Patterns.( |Lambda|_| )
val param : Quotations.Var
val body : Quotations.Expr
val expr : Quotations.Expr
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
val ofQuot : (Quotations.Expr -> Expr)

Full name: LambdaCalculus.ExprModule.ofQuot
Multiple items
module FSharp

from LambdaCalculus.ExprModule

Interop with F# quotations.

--------------------
namespace Microsoft.FSharp
namespace FParsec
val private parseExpr : Parser<Expr,unit>

Full name: LambdaCalculus.ExprModule.Parse.parseExpr
val private parseExprRef : Parser<Expr,unit> ref

Full name: LambdaCalculus.ExprModule.Parse.parseExprRef
val createParserForwardedToRef : unit -> Parser<'a,'u> * Parser<'a,'u> ref

Full name: FParsec.Primitives.createParserForwardedToRef
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val private parseName : Parser<string,unit>

Full name: LambdaCalculus.ExprModule.Parse.parseName
val many1Chars : Parser<char,'u> -> Parser<string,'u>

Full name: FParsec.CharParsers.many1Chars
val satisfy : (char -> bool) -> Parser<char,'u>

Full name: FParsec.CharParsers.satisfy
val c : char
type Char =
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 1 overload
static val MaxValue : char
static val MinValue : char
static member ConvertFromUtf32 : utf32:int -> string
static member ConvertToUtf32 : highSurrogate:char * lowSurrogate:char -> int + 1 overload
static member GetNumericValue : c:char -> float + 1 overload
...
end

Full name: System.Char
Char.IsLetterOrDigit(c: char) : bool
Char.IsLetterOrDigit(s: string, index: int) : bool
val private parseVariable : Parser<Expr,unit>

Full name: LambdaCalculus.ExprModule.Parse.parseVariable
val private parseApplication : Parser<Expr,unit>

Full name: LambdaCalculus.ExprModule.Parse.parseApplication
val pipe5 : Parser<'a,'u> -> Parser<'b,'u> -> Parser<'c,'u> -> Parser<'d,'u> -> Parser<'e,'u> -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> Parser<'f,'u>

Full name: FParsec.Primitives.pipe5
val skipChar : char -> Parser<unit,'u>

Full name: FParsec.CharParsers.skipChar
val many1 : Parser<'a,'u> -> Parser<'a list,'u>

Full name: FParsec.Primitives.many1
val private parseLambda : Parser<Expr,unit>

Full name: LambdaCalculus.ExprModule.Parse.parseLambda
val pipe4 : Parser<'a,'u> -> Parser<'b,'u> -> Parser<'c,'u> -> Parser<'d,'u> -> ('a -> 'b -> 'c -> 'd -> 'e) -> Parser<'e,'u>

Full name: FParsec.Primitives.pipe4
val skipAnyOf : seq<char> -> Parser<unit,'u>

Full name: FParsec.CharParsers.skipAnyOf
val param : string
val choice : seq<Parser<'a,'u>> -> Parser<'a,'u>

Full name: FParsec.Primitives.choice
val private parse : str:string -> Expr

Full name: LambdaCalculus.ExprModule.Parse.parse
val str : string
val parser : Parser<Expr,unit>
val eof : Parser<unit,'u>

Full name: FParsec.CharParsers.eof
val run : Parser<'Result,unit> -> string -> ParserResult<'Result,unit>

Full name: FParsec.CharParsers.run
union case ParserResult.Success: 'Result * 'UserState * Position -> ParserResult<'Result,'UserState>
val expr : Expr
union case ParserResult.Failure: string * ParserError * 'UserState -> ParserResult<'Result,'UserState>
val msg : string
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val parse : (string -> Expr)

Full name: LambdaCalculus.ExprModule.parse
module Parse

from LambdaCalculus.ExprModule
val toString : expr:Expr -> string

Full name: LambdaCalculus.ExprModule.toString
override Expr.ToString : unit -> string

Converts expression to string.
val occurs : name:Variable -> _arg1:Expr -> bool

Full name: LambdaCalculus.ExprModule.occurs

Indicates whether the given variable occurs within a lambda expression (either
bound or free).
val name' : Variable
val occursFree : name:Variable -> _arg1:Expr -> bool

Full name: LambdaCalculus.ExprModule.occursFree

Indicates whether the given variable occurs free within a lambda expression.
(Note that it might occur both free and bound.)
val alphaConvert : newName:Variable -> lambda:Expr -> Expr

Full name: LambdaCalculus.ExprModule.alphaConvert

α-conversion.
val newName : Variable
val lambda : Expr
val convert : (Variable -> Variable -> Expr -> Expr)
val oldName : Variable
val convert : (Expr -> Expr)
module Option

from Microsoft.FSharp.Core
val defaultWith : defThunk:(unit -> 'a) -> option:'a option -> 'a

Full name: LambdaCalculus.ExprModule.Option.defaultWith
val defThunk : (unit -> 'a)
Multiple items
val option : 'a option

--------------------
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val v : 'a
val substitute : arg:Expr -> param:Variable -> body:Expr -> Expr

Full name: LambdaCalculus.ExprModule.substitute

Replaces all occurrences of param with arg in body.
val allVariables : (Expr -> Set<string>)

Answers the set of all variables in the given expression.
val loop : (Expr -> seq<string>)
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
Multiple items
module Set

from Microsoft.FSharp.Collections

--------------------
type Set<'T (requires comparison)> =
interface IComparable
interface IEnumerable
interface IEnumerable<'T>
interface ICollection<'T>
new : elements:seq<'T> -> Set<'T>
member Add : value:'T -> Set<'T>
member Contains : value:'T -> bool
override Equals : obj -> bool
member IsProperSubsetOf : otherSet:Set<'T> -> bool
member IsProperSupersetOf : otherSet:Set<'T> -> bool
...

Full name: Microsoft.FSharp.Collections.Set<_>

--------------------
new : elements:seq<'T> -> Set<'T>
val ofSeq : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.ofSeq
val subst : (Expr -> Expr)
val param' : Variable
val body' : Expr
val allVars : Set<string>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
Char.ToString() : string
Char.ToString(provider: IFormatProvider) : string
val tryFind : predicate:('T -> bool) -> source:seq<'T> -> 'T option

Full name: Microsoft.FSharp.Collections.Seq.tryFind
val newName : string
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
member Set.Contains : value:'T -> bool
Multiple items
module Option

from LambdaCalculus.ExprModule

--------------------
module Option

from Microsoft.FSharp.Core
val map : mapping:('T -> 'U) -> option:'T option -> 'U option

Full name: Microsoft.FSharp.Core.Option.map
val betaReduce : _arg1:Expr -> Expr

Full name: LambdaCalculus.ExprModule.betaReduce

Reduces a β-reduction expression ("β-redex"). This is
function evaluation, which "calls" the given lambda
with the given argument.
val eval : expr:Expr -> Expr

Full name: LambdaCalculus.ExprModule.eval

Evaluates the given expression lazily (normal order).
See reduceLeftmostOutermostBetaRedex and reduceToNormalForm in
https://opendsa-server.cs.vt.edu/ODSA/AV/PL/interpreters/lambdacalc/version1.4.used.in.book/scripts/interpreter.js
val containsBetaRedex : (Expr -> bool)
val reduceLazy : (Expr -> Expr)
val loop : (Expr -> Expr)
Multiple items
type AutoOpenAttribute =
inherit Attribute
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
member Path : string

Full name: Microsoft.FSharp.Core.AutoOpenAttribute

--------------------
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
val True : Expr

Full name: LambdaCalculus.Lang.True
val x : obj
val y : obj
Multiple items
module Expr

from LambdaCalculus

Lambda expression functions.

--------------------
type Expr =
| Variable of Variable
| Application of (Expr * Expr)
| Lambda of (Variable * Expr)
override ToString : unit -> string
member String : Variable

Full name: LambdaCalculus.Expr

Lambda expression.
val False : Expr

Full name: LambdaCalculus.Lang.False
val If : Expr

Full name: LambdaCalculus.Lang.If
val b : (obj -> obj -> obj)
val And : Expr

Full name: LambdaCalculus.Lang.And
val Or : Expr

Full name: LambdaCalculus.Lang.Or
val Zero : Expr

Full name: LambdaCalculus.Lang.Zero
val f : obj
val One : Expr

Full name: LambdaCalculus.Lang.One
val f : (obj -> obj)
val Two : Expr

Full name: LambdaCalculus.Lang.Two
val Three : Expr

Full name: LambdaCalculus.Lang.Three
val Four : Expr

Full name: LambdaCalculus.Lang.Four
val Five : Expr

Full name: LambdaCalculus.Lang.Five
val Six : Expr

Full name: LambdaCalculus.Lang.Six
val Seven : Expr

Full name: LambdaCalculus.Lang.Seven
val Eight : Expr

Full name: LambdaCalculus.Lang.Eight
val Nine : Expr

Full name: LambdaCalculus.Lang.Nine
val Ten : Expr

Full name: LambdaCalculus.Lang.Ten
val Succ : Expr

Full name: LambdaCalculus.Lang.Succ
val n : ((obj -> obj) -> obj -> obj)
val Plus : Expr

Full name: LambdaCalculus.Lang.Plus
val m : (obj -> obj -> obj)
val n : (obj -> obj -> obj)
val Mult : Expr

Full name: LambdaCalculus.Lang.Mult
val m : (obj -> obj)
val n : (obj -> obj)
val Y : Expr

Full name: LambdaCalculus.Lang.Y

Y-combinator for recursion
module Program

from LambdaCalculus
Multiple items
type EntryPointAttribute =
inherit Attribute
new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
val main : argv:string [] -> int

Full name: LambdaCalculus.Program.main
val argv : string []
type Console =
static member BackgroundColor : ConsoleColor with get, set
static member Beep : unit -> unit + 1 overload
static member BufferHeight : int with get, set
static member BufferWidth : int with get, set
static member CapsLock : bool
static member Clear : unit -> unit
static member CursorLeft : int with get, set
static member CursorSize : int with get, set
static member CursorTop : int with get, set
static member CursorVisible : bool with get, set
...

Full name: System.Console
property Console.OutputEncoding: Text.Encoding
namespace System.Text
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...

Full name: System.Text.Encoding
property Text.Encoding.Unicode: Text.Encoding
val IsZero : Expr
val Pred : Expr
val TriangleNonRecursive : Expr
val TriangleRecursive : Expr
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn