Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kekyo/typeinferencer

Algorithm W and Algorithm M in F#
https://github.com/kekyo/typeinferencer

algorithm-m algorithm-w ast fsharp functional type-inference

Last synced: 14 days ago
JSON representation

Algorithm W and Algorithm M in F#

Awesome Lists containing this project

README

        

# Algorithm W and Algorithm M in F#

[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)

[![NuGet TypeInferencer](https://img.shields.io/nuget/v/TypeInferencer.svg?style=flat)](https://www.nuget.org/packages/TypeInferencer)
[![CI build (main)](https://github.com/kekyo/TypeInferencer/workflows/.NET/badge.svg?branch=main)](https://github.com/kekyo/TypeInferencer/actions?query=branch%3Amain)

## What is this?

This is a type inference implementation of both `Algorithm W` and `Algorithm M` written in F#.

Referenced articles:

1. [`Algorithm W Step by Step`](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.65.7733&rep=rep1&type=pdf)
2. [`Proofs about a Folklore Let-Polymorphic Type
Inference Algorithm`](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.29.4595&rep=rep1&type=pdf)

The method of article 1 was implemented with care not to change it as much as possible.

### Example

```fsharp
// NuGet package is available.
#r "nuget: TypeInferencer"

open TypeInferencer

// `let id = fun x -> x in id id`
let expr =
ELet("id",
EAbs("x", EVar "x"),
EApp(EVar "id", EVar "id"))

// Type environment (is empty)
let env = TypeEnv []

// Do inferring with `Algorithm W` (top-down)
let actual = infer TopDown env expr

// Pretty printing
printfn "Expression: %s" (show expr)
printfn "Actual: %s" (show actual)
```

Results:

```
Expression: let id = fun x -> x in id id
Actual: a3 -> a3
```

---

## How to play it

A playing guide is here:

* English:
* [Markdown (Inside this repository)](docs/HowToPlay_en.md)
* [Rendered pdf (pandoc/wkhtmltopdf)](docs/HowToPlay_en.pdf)
* Japanese:
* [Markdown (Inside this repository)](docs/HowToPlay_ja.md)
* [Rendered pdf (pandoc/wkhtmltopdf)](docs/HowToPlay_ja.pdf)

---

## Basic interface

### Well-defined types

AST expression type:

```fsharp
type public Lit =
| LInt of value:int32
| LBool of value:bool

type public Exp =
| EVar of name:string
| ELit of literal:Lit
| EApp of func:Exp * arg:Exp
| EAbs of name:string * expr:Exp
| ELet of name:string * expr:Exp * body:Exp
| EFix of func:string * name:string * expr:Exp
```

Result type type:

```fsharp
type public Type =
| TVar of name:string
| TInt
| TBool
| TFun of parameterType:Type * resultType:Type
```

The inferencer:

```fsharp
type public InferAlgorithm =
| TopDown
| BottomUp

[]
module public Inferencer =
let infer: InferAlgorithm -> TypeEnv -> Exp -> Type
```

---

### Requirements

* F# 6.0 or upper
* NuGet package supported platforms:
* net8.0
* net7.0
* net6.0
* net5.0
* netcoreapp3.1
* netcoreapp2.1
* netstandard2.1
* netstandard2.0
* net48
* net461

### License

Copyright (c) Kouji Matsui (@kozy_kekyo, @kekyo2)

License under Apache-v2.