From 6f6bfea11f411c0bb803d067cdfa086b6225fd43 Mon Sep 17 00:00:00 2001 From: Giulio Canti Date: Mon, 12 Sep 2016 10:39:53 +0200 Subject: [PATCH] prepare first release, ref #21 (#22) --- .babelrc | 2 +- .gitignore | 3 +- .npmignore | 5 -- CHANGELOG.md | 17 ++++ LICENSE | 21 +++++ README.md | 88 +++++-------------- QuickCheck.js => examples/QuickCheck.js | 28 +++--- React.js => examples/React.js | 8 +- Signal.js => examples/Signal.js | 20 ++--- exercises/answer1.js | 4 +- exercises/answer2.js | 4 +- exercises/answer3.js | 4 +- exercises/answer4.js | 8 +- exercises/answer5.js | 8 +- exercises/answer6.js | 8 +- exercises/exercise2.js | 2 +- exercises/exercise4.js | 4 +- exercises/exercise5.js | 4 +- exercises/exercise6.js | 2 +- package.json | 21 +++-- playground/index.html | 13 --- playground/index.js | 14 --- playground/webpack.config.js | 17 ---- Aff.js => src/Aff.js | 0 Alt.js => src/Alt.js | 0 Alternative.js => src/Alternative.js | 0 Applicative.js => src/Applicative.js | 0 Apply.js => src/Apply.js | 0 Arr.js => src/Arr.js | 0 Bifunctor.js => src/Bifunctor.js | 0 Category.js => src/Category.js | 0 Chain.js => src/Chain.js | 0 Comonad.js => src/Comonad.js | 0 Compose.js => src/Compose.js | 0 Console.js => src/Console.js | 0 Contravariant.js => src/Contravariant.js | 0 Data.js => src/Data.js | 0 Eff.js => src/Eff.js | 0 Either.js => src/Either.js | 23 +++-- Exception.js => src/Exception.js | 0 Extend.js => src/Extend.js | 0 Foldable.js => src/Foldable.js | 0 Free.js => src/Free.js | 24 ++--- Fun.js => src/Fun.js | 0 Functor.js => src/Functor.js | 0 HKT.js => src/HKT.js | 0 HeytingAlgebra.js => src/HeytingAlgebra.js | 0 Identity.js => src/Identity.js | 0 Leibnitz.js => src/Leibnitz.js | 0 Maybe.js => src/Maybe.js | 0 Monad.js => src/Monad.js | 0 Monoid.js => src/Monoid.js | 0 .../NaturalTransformation.js | 0 Ord.js => src/Ord.js | 0 Ordering.js => src/Ordering.js | 0 Plus.js => src/Plus.js | 0 Profunctor.js => src/Profunctor.js | 0 Random.js => src/Random.js | 0 Reader.js => src/Reader.js | 0 Semigroup.js => src/Semigroup.js | 0 Semigroupoid.js => src/Semigroupoid.js | 0 Setoid.js => src/Setoid.js | 0 State.js => src/State.js | 0 Traversable.js => src/Traversable.js | 0 Tuple.js => src/Tuple.js | 0 Unfoldable.js => src/Unfoldable.js | 0 Unsafe.js => src/Unsafe.js | 0 Validation.js => src/Validation.js | 2 +- Writer.js => src/Writer.js | 0 test/Aff.js | 12 +-- test/Arr.js | 8 +- test/Either.js | 31 +++++++ test/Exception.js | 10 +-- test/Fun.js | 2 +- test/Maybe.js | 2 +- test/Random.js | 4 +- test/Signal.js | 4 +- 77 files changed, 204 insertions(+), 223 deletions(-) delete mode 100644 .npmignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE rename QuickCheck.js => examples/QuickCheck.js (81%) rename React.js => examples/React.js (92%) rename Signal.js => examples/Signal.js (90%) delete mode 100644 playground/index.html delete mode 100644 playground/index.js delete mode 100644 playground/webpack.config.js rename Aff.js => src/Aff.js (100%) rename Alt.js => src/Alt.js (100%) rename Alternative.js => src/Alternative.js (100%) rename Applicative.js => src/Applicative.js (100%) rename Apply.js => src/Apply.js (100%) rename Arr.js => src/Arr.js (100%) rename Bifunctor.js => src/Bifunctor.js (100%) rename Category.js => src/Category.js (100%) rename Chain.js => src/Chain.js (100%) rename Comonad.js => src/Comonad.js (100%) rename Compose.js => src/Compose.js (100%) rename Console.js => src/Console.js (100%) rename Contravariant.js => src/Contravariant.js (100%) rename Data.js => src/Data.js (100%) rename Eff.js => src/Eff.js (100%) rename Either.js => src/Either.js (93%) rename Exception.js => src/Exception.js (100%) rename Extend.js => src/Extend.js (100%) rename Foldable.js => src/Foldable.js (100%) rename Free.js => src/Free.js (74%) rename Fun.js => src/Fun.js (100%) rename Functor.js => src/Functor.js (100%) rename HKT.js => src/HKT.js (100%) rename HeytingAlgebra.js => src/HeytingAlgebra.js (100%) rename Identity.js => src/Identity.js (100%) rename Leibnitz.js => src/Leibnitz.js (100%) rename Maybe.js => src/Maybe.js (100%) rename Monad.js => src/Monad.js (100%) rename Monoid.js => src/Monoid.js (100%) rename NaturalTransformation.js => src/NaturalTransformation.js (100%) rename Ord.js => src/Ord.js (100%) rename Ordering.js => src/Ordering.js (100%) rename Plus.js => src/Plus.js (100%) rename Profunctor.js => src/Profunctor.js (100%) rename Random.js => src/Random.js (100%) rename Reader.js => src/Reader.js (100%) rename Semigroup.js => src/Semigroup.js (100%) rename Semigroupoid.js => src/Semigroupoid.js (100%) rename Setoid.js => src/Setoid.js (100%) rename State.js => src/State.js (100%) rename Traversable.js => src/Traversable.js (100%) rename Tuple.js => src/Tuple.js (100%) rename Unfoldable.js => src/Unfoldable.js (100%) rename Unsafe.js => src/Unsafe.js (100%) rename Validation.js => src/Validation.js (86%) rename Writer.js => src/Writer.js (100%) create mode 100644 test/Either.js diff --git a/.babelrc b/.babelrc index 9c25be0..4f9ae3d 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,5 @@ { - "presets": ["es2015"], + "presets": ["es2015", "react"], "plugins" : [ "syntax-flow", "transform-flow-strip-types", diff --git a/.gitignore b/.gitignore index 77dcf13..2b5d8d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.log -node_modules dev +lib +node_modules diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 3316590..0000000 --- a/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -*.log -node_modules -dev -playground -exercises diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..170d98b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +> **Tags:** +> - [New Feature] +> - [Bug Fix] +> - [Breaking Change] +> - [Documentation] +> - [Internal] +> - [Polish] +> - [Experimental] + +**Note**: Gaps between patch versions are faulty/broken releases. +**Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice. + +## 0.1.0 + +Initial release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6cda82d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Giulio Canti + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 04c267d..c86b883 100644 --- a/README.md +++ b/README.md @@ -2,35 +2,15 @@ - statically type checked by [Flow](https://flowtype.org/) - PureScript-like standard library -- static land compatible ([Specification](https://github.com/rpominov/static-land)) +- [static land](https://github.com/rpominov/static-land) compatible The idea (faking higher kinded types in Flow) is based on the paper [Lightweight higher-kinded polymorphism](https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf) and [elm-brands](https://github.com/joneshf/elm-brands). -# Try it out - -``` -git clone https://github.com/gcanti/flow-static-land.git -cd flow-static-land -npm install -npm start - -# execute ./node_modules/.bin/babel-node playground/index.js -# or open the page playground/index.html in a browser -# then edit playground/index.js -``` - -# Examples - -Real world examples - -- a Signal library ([purescript-signal](https://github.com/bodil/purescript-signal) porting) -- a QuickCheck library ([purescript-quickcheck](https://github.com/purescript/purescript-quickcheck) partial porting) - -## `Maybe` and `Arr` +# Example ```js -import * as maybe from 'flow-static-land/Maybe' -import * as arr from 'flow-static-land/Arr' +import * as maybe from 'flow-static-land/lib/Maybe' +import * as arr from 'flow-static-land/lib/Arr' const f = (n) => n * 2 const g = (n) => n + 1 @@ -63,47 +43,28 @@ const f = (n) => n * 2 ^^^^^ number ``` -## Expressing side effects with the `Eff` monad +# Related blog posts -See this [blog post](https://medium.com/@gcanti/the-eff-monad-implemented-in-flow-40803670c3eb#.sj4m00hpe) for context - -```js -import type { Eff } from 'flow-static-land/Eff' -import { inj } from 'flow-static-land/Eff' +- [Higher kinded types with Flow](https://medium.com/@gcanti/higher-kinded-types-in-flow-275b657992b7) +- [Expressing side effects with the `Eff` monad](https://medium.com/@gcanti/the-eff-monad-implemented-in-flow-40803670c3eb) +- [Phantom types with Flow](https://medium.com/@gcanti/phantom-types-with-flow-828aff73232b) +- [Refinements with Flow](https://medium.com/@gcanti/refinements-with-flow-9c7eeae8478b) -class DB {} +# More examples -type User = { - username: string, - uid: number -}; - -const users = {} -let uid = 0 - -function createUser(username: string): Eff<{ write: DB }, User> { - return inj(() => { - users[username] = { username, uid: ++uid } - return users[username] - }) -} +`examples` directory: -function lookupUser(username: string): Eff<{ read: DB }, ?User> { - return inj(() => users[username]) -} - -// the signature shows that createThenLookupUser will read and write to the db -const createThenLookupUser: (username: string) => Eff<{ read: DB, write: DB }, ?User> = - username => chain(user => lookupUser(user.username), createUser(username)) -``` +- a Signal library ([purescript-signal](https://github.com/bodil/purescript-signal) porting) +- a QuickCheck library ([purescript-quickcheck](https://github.com/purescript/purescript-quickcheck) partial porting) +- a React library (experimental) # Setup -Download the source code with the command `npm i gcanti/flow-static-land#master` - -**Bundles** +```sh +npm install flow-static-land --save +``` -In order to build a bundle, add the following plugins to your `.babelrc` file +Babel config ``` { @@ -116,15 +77,6 @@ In order to build a bundle, add the following plugins to your `.babelrc` file } ``` -For webpack, add the following include to your babel loader - -```js -{ - loader: 'babel', - include: [ - path.resolve(__dirname, "node_modules/flow-static-land"), - path.resolve(__dirname, "path/to/your/code") - ] -} -``` +# License +The MIT License (MIT) diff --git a/QuickCheck.js b/examples/QuickCheck.js similarity index 81% rename from QuickCheck.js rename to examples/QuickCheck.js index 7cf2c01..9c29ccf 100644 --- a/QuickCheck.js +++ b/examples/QuickCheck.js @@ -6,20 +6,20 @@ */ -import type { Eff } from './Eff' -import * as eff from './Eff' -import { CONSOLE } from './Console' -import { RANDOM, random } from './Random' -import { EXCEPTION, throwException, error } from './Exception' -import type { State } from './State' -import * as state from './State' -import type { Arr } from './Arr' -import * as arr from './Arr' -import { log } from './Console' -import type { Either } from './Either' -import * as either from './Either' -import { replicateA } from './Unfoldable' -import * as tuple from './Tuple' +import type { Eff } from '../src/Eff' +import * as eff from '../src/Eff' +import { CONSOLE } from '../src/Console' +import { RANDOM, random } from '../src/Random' +import { EXCEPTION, throwException, error } from '../src/Exception' +import type { State } from '../src/State' +import * as state from '../src/State' +import type { Arr } from '../src/Arr' +import * as arr from '../src/Arr' +import { log } from '../src/Console' +import type { Either } from '../src/Either' +import * as either from '../src/Either' +import { replicateA } from '../src/Unfoldable' +import * as tuple from '../src/Tuple' /* diff --git a/React.js b/examples/React.js similarity index 92% rename from React.js rename to examples/React.js index 4cb997d..ef76151 100644 --- a/React.js +++ b/examples/React.js @@ -1,8 +1,8 @@ // @flow -import { HKT } from './HKT' -import type { Contravariant } from './Contravariant' -import type { Arr } from './Arr' -import * as arr from './Arr' +import { HKT } from '../src/HKT' +import type { Contravariant } from '../src/Contravariant' +import type { Arr } from '../src/Arr' +import * as arr from '../src/Arr' import React from 'react' class IsReactComponent {} diff --git a/Signal.js b/examples/Signal.js similarity index 90% rename from Signal.js rename to examples/Signal.js index de996f4..402e6d6 100644 --- a/Signal.js +++ b/examples/Signal.js @@ -6,16 +6,16 @@ */ -import type { Applicative } from './Applicative' -import type { Functor } from './Functor' -import type { Semigroup } from './Semigroup' -import type { Foldable } from './Foldable' -import type { Maybe } from './Maybe' -import type { Setoid } from './Setoid' -import type { Predicate } from './Fun' - -import { HKT } from './HKT' -import * as maybe from './Maybe' +import type { Applicative } from '../src/Applicative' +import type { Functor } from '../src/Functor' +import type { Semigroup } from '../src/Semigroup' +import type { Foldable } from '../src/Foldable' +import type { Maybe } from '../src/Maybe' +import type { Setoid } from '../src/Setoid' +import type { Predicate } from '../src/Fun' + +import { HKT } from '../src/HKT' +import * as maybe from '../src/Maybe' class IsSignal {} diff --git a/exercises/answer1.js b/exercises/answer1.js index 228b941..0178c79 100644 --- a/exercises/answer1.js +++ b/exercises/answer1.js @@ -1,7 +1,7 @@ // @flow -import type { Ord } from '../Ord' -import { numberOrd, stringOrd } from '../Ord' +import type { Ord } from '../src/Ord' +import { numberOrd, stringOrd } from '../src/Ord' export function binarySearch(xs: Array, x: A, ord: Ord): number { function go(low: number, mid: number, high: number): number { diff --git a/exercises/answer2.js b/exercises/answer2.js index 0ca05bb..10a1e5a 100644 --- a/exercises/answer2.js +++ b/exercises/answer2.js @@ -1,7 +1,7 @@ // @flow -import type { Ord } from '../Ord' -import { greaterThan, numberOrd } from '../Ord' +import type { Ord } from '../src/Ord' +import { greaterThan, numberOrd } from '../src/Ord' export function isSorted(xs: Array, ord: Ord): boolean { const len = xs.length diff --git a/exercises/answer3.js b/exercises/answer3.js index 8c2f894..0c739d0 100644 --- a/exercises/answer3.js +++ b/exercises/answer3.js @@ -1,7 +1,7 @@ // @flow -import { HKT } from '../HKT' -import type { Functor } from '../Functor' +import { HKT } from '../src/HKT' +import type { Functor } from '../src/Functor' class IsList {} diff --git a/exercises/answer4.js b/exercises/answer4.js index 8af93fc..2c5a5a6 100644 --- a/exercises/answer4.js +++ b/exercises/answer4.js @@ -1,7 +1,7 @@ // @flow -import type { Maybe } from '../Maybe' -import * as maybe from '../Maybe' +import type { Maybe } from '../src/Maybe' +import * as maybe from '../src/Maybe' export function head(xs: Array): Maybe { if (xs.length) { @@ -13,8 +13,8 @@ export function head(xs: Array): Maybe { console.log(head([1, 2, 3])) // => 1 console.log(head([])) // => null -import type { Either } from '../Either' -import * as either from '../Either' +import type { Either } from '../src/Either' +import * as either from '../src/Either' export function elementAt(xs: Array, i: number): Either { if (i < 0) { diff --git a/exercises/answer5.js b/exercises/answer5.js index 8c730b1..68797b5 100644 --- a/exercises/answer5.js +++ b/exercises/answer5.js @@ -1,10 +1,10 @@ // @flow -import type { Maybe } from '../Maybe' -import * as maybe from '../Maybe' +import type { Maybe } from '../src/Maybe' +import * as maybe from '../src/Maybe' -import type { Arr } from '../Arr' -import * as arr from '../Arr' +import type { Arr } from '../src/Arr' +import * as arr from '../src/Arr' export function getAllJustsOrNothing(xs: Arr>): Maybe> { return arr.sequence(maybe, xs) diff --git a/exercises/answer6.js b/exercises/answer6.js index 8615528..5b7bee6 100644 --- a/exercises/answer6.js +++ b/exercises/answer6.js @@ -1,9 +1,9 @@ // @flow -import type { Arr } from '../Arr' -import * as arr from '../Arr' -import * as maybe from '../Maybe' -import * as tuple from '../Tuple' +import type { Arr } from '../src/Arr' +import * as arr from '../src/Arr' +import * as maybe from '../src/Maybe' +import * as tuple from '../src/Tuple' export function evens(count: number): Arr { return arr.unfoldr(n => { diff --git a/exercises/exercise2.js b/exercises/exercise2.js index 8f27247..4ccfec3 100644 --- a/exercises/exercise2.js +++ b/exercises/exercise2.js @@ -8,7 +8,7 @@ */ -import type { Ord } from '../Ord' +import type { Ord } from '../src/Ord' export function isSorted(xs: Array, ord: Ord): boolean { throw 'not implemented' diff --git a/exercises/exercise4.js b/exercises/exercise4.js index a21295a..b99ffeb 100644 --- a/exercises/exercise4.js +++ b/exercises/exercise4.js @@ -7,7 +7,7 @@ Write a type safe head function. */ -import type { Maybe } from '../Maybe' +import type { Maybe } from '../src/Maybe' export function head(xs: Array): Maybe { throw 'not implemented' @@ -18,7 +18,7 @@ export function head(xs: Array): Maybe { Write a type safe elementAt function */ -import type { Either } from '../Either' +import type { Either } from '../src/Either' export function elementAt(xs: Array, i: number): Either { throw 'not implemented' diff --git a/exercises/exercise5.js b/exercises/exercise5.js index 876663f..b2cd7e0 100644 --- a/exercises/exercise5.js +++ b/exercises/exercise5.js @@ -10,8 +10,8 @@ Just with a list of all the values */ -import type { Arr } from '../Arr' -import type { Maybe } from '../Maybe' +import type { Arr } from '../src/Arr' +import type { Maybe } from '../src/Maybe' export function getAllJustsOrNothing(xs: Arr>): Maybe> { throw 'not implemented' diff --git a/exercises/exercise6.js b/exercises/exercise6.js index f03f9f1..d66cd90 100644 --- a/exercises/exercise6.js +++ b/exercises/exercise6.js @@ -9,7 +9,7 @@ Hint: use arr.unfoldr */ -import type { Arr } from '../Arr' +import type { Arr } from '../src/Arr' export function evens(count: number): Arr { throw 'not implemented' diff --git a/package.json b/package.json index 3280559..53596ee 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,16 @@ { "name": "flow-static-land", - "version": "0.1.0", - "description": "Implementation of common algebraic types in JavaScript + Flow based on static-land", + "version": "0.0.1", + "description": "Implementation of common algebraic types in JavaScript + Flow", + "files": [ + "lib", + "src" + ], "scripts": { "dev": "webpack --config=dev/webpack.config.js --watch --progress", - "start": "webpack --config=playground/webpack.config.js --watch --progress", - "test": "mocha --compilers js:babel-register" + "lint": "eslint src test", + "test": "mocha --compilers js:babel-register", + "build": "rm -rf lib/* && babel src -d lib && flow-copy-source -v src lib" }, "repository": { "type": "git", @@ -25,21 +30,25 @@ "babel-plugin-transform-class-properties": "^6.11.5", "babel-plugin-transform-flow-strip-types": "^6.8.0", "babel-preset-es2015": "^6.13.2", + "babel-preset-react": "^6.11.1", "eslint": "^2.12.0", "eslint-plugin-flow-vars": "^0.4.0", + "flow-copy-source": "^1.1.0", "mocha": "^3.0.2" }, "tags": [ "flow", "flowtype", - "static-land", + "static land", + "fantasy land", "algebraic types", "functional programming" ], "keywords": [ "flow", "flowtype", - "static-land", + "static land", + "fantasy land", "algebraic types", "functional programming" ] diff --git a/playground/index.html b/playground/index.html deleted file mode 100644 index c3541f2..0000000 --- a/playground/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - flow-static-land playground - - - - - - diff --git a/playground/index.js b/playground/index.js deleted file mode 100644 index 64f66c1..0000000 --- a/playground/index.js +++ /dev/null @@ -1,14 +0,0 @@ -// @flow - -import * as maybe from '../Maybe' -import * as arr from '../Arr' - -const f = (n) => n * 2 -const g = (n) => n + 1 - -console.log(maybe.map(f, maybe.Nothing)) // => null -console.log(maybe.map(f, maybe.of(3))) // => 6 - -console.log(arr.ap(arr.inj([f, g]), arr.inj([1, 2, 3]))) // => [2, 4, 6, 2, 3, 4] - -// maybe.map(f, maybe.of('s')) // <= uncomment this to see flow errors diff --git a/playground/webpack.config.js b/playground/webpack.config.js deleted file mode 100644 index 4e63b07..0000000 --- a/playground/webpack.config.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable */ -var path = require('path'); - -module.exports = { - entry: './playground/index.js', - output: { - path: path.resolve(__dirname), - filename: 'bundle.js' - }, - module: { - loaders: [ - { - loader: 'babel' - } - ] - } -}; diff --git a/Aff.js b/src/Aff.js similarity index 100% rename from Aff.js rename to src/Aff.js diff --git a/Alt.js b/src/Alt.js similarity index 100% rename from Alt.js rename to src/Alt.js diff --git a/Alternative.js b/src/Alternative.js similarity index 100% rename from Alternative.js rename to src/Alternative.js diff --git a/Applicative.js b/src/Applicative.js similarity index 100% rename from Applicative.js rename to src/Applicative.js diff --git a/Apply.js b/src/Apply.js similarity index 100% rename from Apply.js rename to src/Apply.js diff --git a/Arr.js b/src/Arr.js similarity index 100% rename from Arr.js rename to src/Arr.js diff --git a/Bifunctor.js b/src/Bifunctor.js similarity index 100% rename from Bifunctor.js rename to src/Bifunctor.js diff --git a/Category.js b/src/Category.js similarity index 100% rename from Category.js rename to src/Category.js diff --git a/Chain.js b/src/Chain.js similarity index 100% rename from Chain.js rename to src/Chain.js diff --git a/Comonad.js b/src/Comonad.js similarity index 100% rename from Comonad.js rename to src/Comonad.js diff --git a/Compose.js b/src/Compose.js similarity index 100% rename from Compose.js rename to src/Compose.js diff --git a/Console.js b/src/Console.js similarity index 100% rename from Console.js rename to src/Console.js diff --git a/Contravariant.js b/src/Contravariant.js similarity index 100% rename from Contravariant.js rename to src/Contravariant.js diff --git a/Data.js b/src/Data.js similarity index 100% rename from Data.js rename to src/Data.js diff --git a/Eff.js b/src/Eff.js similarity index 100% rename from Eff.js rename to src/Eff.js diff --git a/Either.js b/src/Either.js similarity index 93% rename from Either.js rename to src/Either.js index edb1b55..a7b02d4 100644 --- a/Either.js +++ b/src/Either.js @@ -11,22 +11,13 @@ import type { Semigroup } from './Semigroup' import { HKT } from './HKT' import { unsafeCoerce } from './Unsafe' +import { Data1 } from './Data' class IsEither {} -export class Left { - value0: L; - constructor(value0: L) { - this.value0 = value0 - } -} +export class Left extends Data1 {} -export class Right { - value0: R; - constructor(value0: R) { - this.value0 = value0 - } -} +export class Right extends Data1 {} export type EitherV = Left | Right; @@ -145,6 +136,14 @@ export function getSemigroup(semigroup: Semigroup): Semigroup(f: (l: L) => C, g: (r: R) => C, fa: Either): C { + const a = prj(fa) + if (a instanceof Left) { + return f(a.value0) + } + return g(a.value0) +} + export class Do { static of(a: A): Do { return new Do(of(a)) diff --git a/Exception.js b/src/Exception.js similarity index 100% rename from Exception.js rename to src/Exception.js diff --git a/Extend.js b/src/Extend.js similarity index 100% rename from Extend.js rename to src/Extend.js diff --git a/Foldable.js b/src/Foldable.js similarity index 100% rename from Foldable.js rename to src/Foldable.js diff --git a/Free.js b/src/Free.js similarity index 74% rename from Free.js rename to src/Free.js index 194eddc..d643a0d 100644 --- a/Free.js +++ b/src/Free.js @@ -10,11 +10,11 @@ class IsFree {} // we can think of a free monad as just being a list of functors -class Cons extends Data1>> {} +class Suspend extends Data1>> {} -class Nil extends Data1 {} +class Return extends Data1 {} -export type FreeV = Nil | Cons; +export type FreeV = Return | Suspend; export type Free = HKT2; @@ -27,20 +27,20 @@ export function prj(fa: Free): FreeV { } export function of(a: A): Free { - return inj(new Nil(a)) + return inj(new Return(a)) } -export function cons(ffa: HKT>): Free { - return inj(new Cons(ffa)) +export function suspend(ffa: HKT>): Free { + return inj(new Suspend(ffa)) } export function liftFree(functor: Functor, fa: HKT): Free { - return cons(functor.map(of, fa)) + return suspend(functor.map(of, fa)) } export function foldFree(functor: Functor, join: (fa: HKT) => A, ffa: Free): A { const fa = prj(ffa) - if (fa instanceof Nil) { + if (fa instanceof Return) { return fa.value0 } return join(functor.map(x => foldFree(functor, join, x), fa.value0)) @@ -50,10 +50,10 @@ export function freeMonad(functor: Functor): Monad> { function map(f: (a: A) => B, fa: Free): Free { const a = prj(fa) - if (a instanceof Nil) { + if (a instanceof Return) { return of(f(a.value0)) } - return cons(functor.map(x => map(f, x), a.value0)) + return suspend(functor.map(x => map(f, x), a.value0)) } function ap(fab: Free B>, fa: Free): Free { @@ -62,10 +62,10 @@ export function freeMonad(functor: Functor): Monad> { function join(ffa: Free>): Free { const fa = prj(ffa) - if (fa instanceof Nil) { + if (fa instanceof Return) { return fa.value0 } - return cons(functor.map(join, fa.value0)) + return suspend(functor.map(join, fa.value0)) } function chain(f: (a: A) => Free, fa: Free): Free { diff --git a/Fun.js b/src/Fun.js similarity index 100% rename from Fun.js rename to src/Fun.js diff --git a/Functor.js b/src/Functor.js similarity index 100% rename from Functor.js rename to src/Functor.js diff --git a/HKT.js b/src/HKT.js similarity index 100% rename from HKT.js rename to src/HKT.js diff --git a/HeytingAlgebra.js b/src/HeytingAlgebra.js similarity index 100% rename from HeytingAlgebra.js rename to src/HeytingAlgebra.js diff --git a/Identity.js b/src/Identity.js similarity index 100% rename from Identity.js rename to src/Identity.js diff --git a/Leibnitz.js b/src/Leibnitz.js similarity index 100% rename from Leibnitz.js rename to src/Leibnitz.js diff --git a/Maybe.js b/src/Maybe.js similarity index 100% rename from Maybe.js rename to src/Maybe.js diff --git a/Monad.js b/src/Monad.js similarity index 100% rename from Monad.js rename to src/Monad.js diff --git a/Monoid.js b/src/Monoid.js similarity index 100% rename from Monoid.js rename to src/Monoid.js diff --git a/NaturalTransformation.js b/src/NaturalTransformation.js similarity index 100% rename from NaturalTransformation.js rename to src/NaturalTransformation.js diff --git a/Ord.js b/src/Ord.js similarity index 100% rename from Ord.js rename to src/Ord.js diff --git a/Ordering.js b/src/Ordering.js similarity index 100% rename from Ordering.js rename to src/Ordering.js diff --git a/Plus.js b/src/Plus.js similarity index 100% rename from Plus.js rename to src/Plus.js diff --git a/Profunctor.js b/src/Profunctor.js similarity index 100% rename from Profunctor.js rename to src/Profunctor.js diff --git a/Random.js b/src/Random.js similarity index 100% rename from Random.js rename to src/Random.js diff --git a/Reader.js b/src/Reader.js similarity index 100% rename from Reader.js rename to src/Reader.js diff --git a/Semigroup.js b/src/Semigroup.js similarity index 100% rename from Semigroup.js rename to src/Semigroup.js diff --git a/Semigroupoid.js b/src/Semigroupoid.js similarity index 100% rename from Semigroupoid.js rename to src/Semigroupoid.js diff --git a/Setoid.js b/src/Setoid.js similarity index 100% rename from Setoid.js rename to src/Setoid.js diff --git a/State.js b/src/State.js similarity index 100% rename from State.js rename to src/State.js diff --git a/Traversable.js b/src/Traversable.js similarity index 100% rename from Traversable.js rename to src/Traversable.js diff --git a/Tuple.js b/src/Tuple.js similarity index 100% rename from Tuple.js rename to src/Tuple.js diff --git a/Unfoldable.js b/src/Unfoldable.js similarity index 100% rename from Unfoldable.js rename to src/Unfoldable.js diff --git a/Unsafe.js b/src/Unsafe.js similarity index 100% rename from Unsafe.js rename to src/Unsafe.js diff --git a/Validation.js b/src/Validation.js similarity index 86% rename from Validation.js rename to src/Validation.js index 3dfd240..aa6779d 100644 --- a/Validation.js +++ b/src/Validation.js @@ -5,7 +5,7 @@ import type { Either, EitherF } from './Either' import * as either from './Either' -export function validationApplicative(semigroup: Semigroup): Applicative { +export function getApplicative(semigroup: Semigroup): Applicative { function ap(fab: Either B>, fa: Either): Either { const ab = either.prj(fab) const a = either.prj(fa) diff --git a/Writer.js b/src/Writer.js similarity index 100% rename from Writer.js rename to src/Writer.js diff --git a/test/Aff.js b/test/Aff.js index f72cb79..062f6b2 100644 --- a/test/Aff.js +++ b/test/Aff.js @@ -9,7 +9,7 @@ import type { SuccessHandler, Aff, Canceler -} from '../Aff' +} from '../src/Aff' import { inj, runAff, @@ -18,21 +18,21 @@ import { of, ap, chain -} from '../Aff' +} from '../src/Aff' import { error, CONSOLE -} from '../Console' +} from '../src/Console' import { throwException, EXCEPTION -} from '../Exception' +} from '../src/Exception' import type { Eff -} from '../Eff' +} from '../src/Eff' import { runEff -} from '../Eff' +} from '../src/Eff' function testAff(aff, expected) { const e: ErrorHandler<{ err: EXCEPTION }> = throwException diff --git a/test/Arr.js b/test/Arr.js index 9468006..9a72054 100644 --- a/test/Arr.js +++ b/test/Arr.js @@ -1,9 +1,9 @@ // @flow -import * as arr from '../Arr' -import * as maybe from '../Maybe' -import * as tuple from '../Tuple' +import * as arr from '../src/Arr' +import * as maybe from '../src/Maybe' +import * as tuple from '../src/Tuple' import assert from 'assert' -import { numberOrd } from '../Ord' +import { numberOrd } from '../src/Ord' declare var describe: Function; declare var it: Function; diff --git a/test/Either.js b/test/Either.js new file mode 100644 index 0000000..a859f6e --- /dev/null +++ b/test/Either.js @@ -0,0 +1,31 @@ +// @flow + +declare var describe: Function; +declare var it: Function; + +import assert from 'assert' +import { + right, + left, + fromRight, + fromLeft, + map, + either +} from '../src/Either' + +describe('Either', () => { + + it('map', () => { + const f = (s: string): number => s.length + assert.strictEqual(fromRight(map(f, right('s'))), 1) + assert.strictEqual(fromLeft(map(f, left('s'))), 's') + }) + + it('either', () => { + const f = () => 'left' + const g = () => 'right' + assert.strictEqual(either(f, g, right(1)), 'right') + assert.strictEqual(either(f, g, left('s')), 'left') + }) + +}) diff --git a/test/Exception.js b/test/Exception.js index 9c9f629..6c22b61 100644 --- a/test/Exception.js +++ b/test/Exception.js @@ -4,17 +4,17 @@ declare var describe: Function; declare var it: Function; import assert from 'assert' -import type { Eff } from '../Eff' -import { runEff, of } from '../Eff' +import type { Eff } from '../src/Eff' +import { runEff, of } from '../src/Eff' import { EXCEPTION, error, throwException, catchException, tryEff -} from '../Exception' -import type { Either } from '../Either' -import { Left } from '../Either' +} from '../src/Exception' +import type { Either } from '../src/Either' +import { Left } from '../src/Either' describe('Exception', () => { diff --git a/test/Fun.js b/test/Fun.js index 449c2a0..2f3e217 100644 --- a/test/Fun.js +++ b/test/Fun.js @@ -8,7 +8,7 @@ import { compose, pipe, curry -} from '../Fun' +} from '../src/Fun' const f = (n: number) => n + 1 const g = (n: number) => n * 2 diff --git a/test/Maybe.js b/test/Maybe.js index 9c1b38b..825518f 100644 --- a/test/Maybe.js +++ b/test/Maybe.js @@ -12,7 +12,7 @@ import { getMonoid, maybe as maybef, chain -} from '../Maybe' +} from '../src/Maybe' describe('Maybe', () => { diff --git a/test/Random.js b/test/Random.js index 9fc44f8..7b0a1c6 100644 --- a/test/Random.js +++ b/test/Random.js @@ -4,12 +4,12 @@ declare var describe: Function; declare var it: Function; import assert from 'assert' -import { runEff } from '../Eff' +import { runEff } from '../src/Eff' import { randomInt, randomRange, randomBool -} from '../Random' +} from '../src/Random' describe('Random', () => { diff --git a/test/Signal.js b/test/Signal.js index 96a9017..eb167c6 100644 --- a/test/Signal.js +++ b/test/Signal.js @@ -4,7 +4,7 @@ declare var describe: Function; declare var it: Function; import assert from 'assert' -import type { Signal } from '../Signal' +import type { Signal } from '../examples/Signal' import { prj, of, @@ -15,7 +15,7 @@ import { sampleOn, dropRepeats, filter -} from '../Signal' +} from '../examples/Signal' function next(fa: Signal, a: A): void { prj(fa).set(a)