Skip to content

Update dependencies & add build #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
output
bower_components
/.*
!/.gitignore
!/.travis.yml
/bower_components/
/node_modules/
/output/
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
language: node_js
dist: trusty
sudo: required
node_js: 6
install:
- npm install -g bower
- npm install
- bower install
script:
- npm run -s build
after_success:
- >-
test $TRAVIS_TAG &&
echo $GITHUB_TOKEN | pulp login &&
echo y | pulp publish --no-push
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# purescript-freet

[![Latest release](http://img.shields.io/bower/v/purescript-freet.svg)](https://github.com/purescript-contrib/purescript-freet/releases)
[![Latest release](http://img.shields.io/github/release/purescript-contrib/purescript-freet.svg)](https://github.com/purescript-contrib/purescript-freet/releases)
[![Build Status](https://travis-ci.org/purescript-contrib/purescript-freet.svg?branch=master)](https://travis-ci.org/purescript-contrib/purescript-freet)
[![Maintainer: paf31](https://img.shields.io/badge/maintainer-paf31-lightgrey.svg)](http://github.com/paf31)
[![Pursuit](http://pursuit.purescript.org/packages/purescript-freet/badge)](http://pursuit.purescript.org/packages/purescript-freet/)

Free monad transformers
Free monad transformers.

- [Module Documentation](docs/Control/Monad/Free/Trans.md)
- [Example](test/Main.purs)
## Installation

```
bower install purescript-freet
```

## Documentation

Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-freet).
20 changes: 10 additions & 10 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
{
"name": "purescript-freet",
"moduleType": [
"node"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"output"
"node_modules",
"output",
"test",
"bower.json",
"package.json"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/paf31/purescript-freet.git"
},
"dependencies": {
"purescript-console": "^1.0.0-rc.1",
"purescript-control": "^1.0.0-rc.1",
"purescript-tailrec": "^1.0.0-rc.1",
"purescript-transformers": "^1.0.0-rc.1",
"purescript-exists": "^1.0.0-rc.1"
"purescript-console": "^2.0.0",
"purescript-control": "^2.0.0",
"purescript-tailrec": "^2.0.0",
"purescript-transformers": "^2.0.1",
"purescript-exists": "^2.0.0"
}
}
80 changes: 0 additions & 80 deletions docs/Control/Monad/Free/Trans.md

This file was deleted.

13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"private": true,
"scripts": {
"clean": "rimraf output && rimraf .pulp-cache",
"build": "pulp build --censor-lib --strict"
},
"devDependencies": {
"pulp": "^9.0.1",
"purescript-psa": "^0.3.9",
"purescript": "^0.10.1",
"rimraf": "^2.5.4"
}
}
44 changes: 20 additions & 24 deletions src/Control/Monad/Free/Trans.purs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- | This module defines a stack-safe implementation of the _free monad transformer_.

module Control.Monad.Free.Trans
( FreeT()
( FreeT
, freeT
, liftFreeT
, hoistFreeT
Expand All @@ -13,13 +13,12 @@ module Control.Monad.Free.Trans

import Prelude

import Data.Exists (Exists(), mkExists, runExists)
import Data.Either (Either(..))
import Data.Bifunctor (bimap)
import Data.Either (Either(..))
import Data.Exists (Exists, mkExists, runExists)

import Control.Bind ((<=<))
import Control.Monad.Rec.Class (class MonadRec, tailRecM)
import Control.Monad.Trans (class MonadTrans)
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
import Control.Monad.Trans.Class (class MonadTrans)

-- | Instead of implementing `bind` directly, we capture the bind using this data structure, to
-- | evaluate later.
Expand All @@ -40,16 +39,16 @@ freeT = FreeT
resume :: forall f m a. (Functor f, MonadRec m) => FreeT f m a -> m (Either a (f (FreeT f m a)))
resume = tailRecM go
where
go :: FreeT f m a -> m (Either (FreeT f m a) (Either a (f (FreeT f m a))))
go (FreeT f) = map Right (f unit)
go :: FreeT f m a -> m (Step (FreeT f m a) (Either a (f (FreeT f m a))))
go (FreeT f) = map Done (f unit)
go (Bind e) = runExists (\(Bound bound f) ->
case bound unit of
FreeT m -> do
e <- m unit
case e of
Left a -> pure (Left (f a))
Right fc -> pure (Right (Right (map (\h -> h >>= f) fc)))
Bind e1 -> runExists (\(Bound m1 f1) -> pure (Left (bind (m1 unit) (\z -> f1 z >>= f)))) e1) e
Left a -> pure (Loop (f a))
Right fc -> pure (Done (Right (map (\h -> h >>= f) fc)))
Bind e1 -> runExists (\(Bound m1 f1) -> pure (Loop (bind (m1 unit) (\z -> f1 z >>= f)))) e1) e

instance functorFreeT :: (Functor f, Functor m) => Functor (FreeT f m) where
map f (FreeT m) = FreeT \_ -> map (bimap f (map (map f))) (m unit)
Expand All @@ -73,35 +72,32 @@ instance monadTransFreeT :: (Functor f) => MonadTrans (FreeT f) where
instance monadRecFreeT :: (Functor f, Monad m) => MonadRec (FreeT f m) where
tailRecM f = go
where
go s = do
e <- f s
case e of
Left s1 -> go s1
Right a -> pure a
go s =
f s >>= case _ of
Loop s1 -> go s1
Done a -> pure a

-- | Lift an action from the functor `f` to a `FreeT` action.
liftFreeT :: forall f m a. (Functor f, Monad m) => f a -> FreeT f m a
liftFreeT fa = FreeT \_ -> pure (Right (map pure fa))

-- | Change the underlying `Monad` for a `FreeT` action.
hoistFreeT :: forall f m n a. (Functor f, Functor n) => (forall b. m b -> n b) -> FreeT f m a -> FreeT f n a
hoistFreeT :: forall f m n a. (Functor f, Functor n) => (m ~> n) -> FreeT f m a -> FreeT f n a
hoistFreeT = bimapFreeT id

-- | Change the base functor `f` for a `FreeT` action.
interpret :: forall f g m a. (Functor f, Functor m) => (forall b. f b -> g b) -> FreeT f m a -> FreeT g m a
interpret :: forall f g m a. (Functor f, Functor m) => (f ~> g) -> FreeT f m a -> FreeT g m a
interpret nf = bimapFreeT nf id

-- | Change the base functor `f` and the underlying `Monad` for a `FreeT` action.
bimapFreeT :: forall f g m n a. (Functor f, Functor n) => (forall b. f b -> g b) -> (forall b. m b -> n b) -> FreeT f m a -> FreeT g n a
bimapFreeT :: forall f g m n a. (Functor f, Functor n) => (f ~> g) -> (m ~> n) -> FreeT f m a -> FreeT g n a
bimapFreeT nf nm (Bind e) = runExists (\(Bound a f) -> bound (bimapFreeT nf nm <<< a) (bimapFreeT nf nm <<< f)) e
bimapFreeT nf nm (FreeT m) = FreeT \_ -> map (nf <<< map (bimapFreeT nf nm)) <$> nm (m unit)

-- | Run a `FreeT` computation to completion.
runFreeT :: forall f m a. (Functor f, MonadRec m) => (f (FreeT f m a) -> m (FreeT f m a)) -> FreeT f m a -> m a
runFreeT interp = tailRecM (go <=< resume)
where
go :: Either a (f (FreeT f m a)) -> m (Either (FreeT f m a) a)
go (Left a) = pure (Right a)
go (Right fc) = do
c <- interp fc
pure (Left c)
go :: Either a (f (FreeT f m a)) -> m (Step (FreeT f m a) a)
go (Left a) = pure (Done a)
go (Right fc) = Loop <$> interp fc
16 changes: 8 additions & 8 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ module Test.Main where

import Prelude

import Control.Apply
import Control.Monad.Eff
import Control.Monad.Eff.Class
import Control.Monad.Eff.Console
import Control.Monad.Trans
import Control.Monad.Free.Trans
import Control.Monad.Rec.Class
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Free.Trans (FreeT, runFreeT, liftFreeT)
import Control.Monad.Rec.Class (forever)
import Control.Monad.Trans.Class (lift)

data TeletypeF a
= WriteLine String a
Expand All @@ -23,7 +22,7 @@ type Teletype = FreeT TeletypeF
writeLine :: forall m. Monad m => String -> FreeT TeletypeF m Unit
writeLine s = liftFreeT (WriteLine s unit)

readLine :: forall m. Monad m => FreeT TeletypeF m String
readLine :: forall m. Monad m => FreeT TeletypeF m String
readLine = liftFreeT (ReadLine id)

mockTeletype :: forall a eff. Teletype (Eff (console :: CONSOLE | eff)) a -> Eff (console :: CONSOLE | eff) a
Expand All @@ -35,6 +34,7 @@ mockTeletype = runFreeT interp
interp (ReadLine k) = do
pure (k "Fake input")

main :: forall eff. Eff (console :: CONSOLE | eff) Unit
main = mockTeletype $ forever do
lift $ log "Enter some input:"
s <- readLine
Expand Down