Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wildhoney/typified
πΌAn experimental implementation of first class functional types using pure ES at runtime, inspired by Haskell, PureScript and Idris.
https://github.com/wildhoney/typified
declarations functional generics haskell idris purescript types typing
Last synced: 3 days ago
JSON representation
πΌAn experimental implementation of first class functional types using pure ES at runtime, inspired by Haskell, PureScript and Idris.
- Host: GitHub
- URL: https://github.com/wildhoney/typified
- Owner: Wildhoney
- License: mit
- Created: 2018-10-22T21:19:48.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2019-01-03T19:30:56.000Z (almost 6 years ago)
- Last Synced: 2024-11-21T07:09:07.379Z (about 1 month ago)
- Topics: declarations, functional, generics, haskell, idris, purescript, types, typing
- Language: JavaScript
- Homepage: https://typified.herokuapp.com/
- Size: 1.77 MB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
> An experimental implementation of first class functional types using pure ES at runtime, inspired by [Haskell](https://www.haskell.org/), [PureScript](http://www.purescript.org/) and [Idris](https://www.idris-lang.org/).
![Travis](http://img.shields.io/travis/Wildhoney/Typified.svg?style=for-the-badge)
Β
![npm](http://img.shields.io/npm/v/typified.svg?style=for-the-badge)
Β
![License MIT](http://img.shields.io/badge/license-mit-lightgrey.svg?style=for-the-badge)
Β
![Coveralls](https://img.shields.io/coveralls/Wildhoney/Typified.svg?style=for-the-badge)
Β
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=for-the-badge)](https://github.com/prettier/prettier)**npm**: `npm install typified --save`
**cdn**: [`https://cdn.jsdelivr.net/npm/typified@latest/src/index.js`](https://cdn.jsdelivr.net/npm/typified@latest/src/index.js)## Getting Started
With Typified you introduce JavaScript to the world of strong typing in a functional fashion. Instead of the Java-style typing that [TypeScript](https://www.typescriptlang.org/) and [Flow](https://flow.org/) provide, Typified takes the [Haskell](https://en.wikipedia.org/wiki/Haskell_(programming_language)#Code_examples)-inspired approach where types are kept entirely separate from their associated values.
```javascript
import κ½ from 'typified';const sayHello =
t`sayHello β· String β String` (name => `Hello ${name}!`);
```By invoking `sayHello` with a `String` we're guaranteed to be returned a `String` otherwise Typified will throw a `TypeMismatchError` that will notify the developer of such an occurrence. Passing in anything other than `String` will throw the mismatch error.
Typified tries to stay close to the JavaScript world, and thus allows specifying the union operator (`|`) to accept multiple types. For instance our `sayHello` function could take a `Number` type as well and be perfectly fine, as it's not performing any `String`-specific operations β thus we could augment the types to allow `Number` to be passed too.
```javascript
const sayHello =
t`sayHello β· String|Number β String` (name => `Hello ${name}!`);
```Invoking `sayHello` with a `Number` type would be just as fine as invoking it with a `String`.
Typified also supports to the concept of [generics](https://en.wikipedia.org/wiki/Generic_programming). Below we have modified the function a little to accept two name parameters, which yields either one or two greetings depending on whether the names are the same.
```javascript
const sayHello =
t`sayHello β· String β String β String` ((first, second) => {
return first === second
? `Hello ${first}!`
: `Hello ${first} & ${second}!`;
});
```We've removed the `Number` type constraint as we always want to compare `String` types with each other. Invoking `sayHello` as `sayHello('Adam', 100)` would be somewhat pointless as a `String` and `Number` can **never** match with strict equality. However we're still performing a non-`String` exclusive operation, and therefore being able to pass a `Number` would still be rather useful.
You might be tempted to define the type as `String|Number β String|Number β String` however that would still allow the passing of a `String` and a `Number` at the same time. What we need is a way to enforce **any** type as long as both match β generics suddenly become a useful tool.
```javascript
const sayHello =
t`sayHello β· β a. a β a β String` ((first, second) => {
return first === second
? `Hello ${first}!`
: `Hello ${first} & ${second}!`;
});
```Using generics we have the above type annotation which takes a generic `a` β the `a` doesn't yet have a concrete type, and will instead assume a concrete type when the function is invoked. Passing a `Number` as `firstName` would cause `a` to be of type `Number`, and therefore ensure that `secondName` is also a `Number`. Likewise passing `String` as the first parameter would give `a` a type of `String`.
You can define as many generics as you wish in the type annotation, but it's crucial that you define them using `β` or `forall` as otherwise the types would be assumed to be concrete types. In Haskell it's perfectly valid to not define generics, whereas in [PureScript](http://www.purescript.org/) the defining of generics is mandatory β Typified also takes this approach.