Skip to content

Commit 5dd693d

Browse files
committed
Merge branch 'topic/implementation'
2 parents 4aeb3ed + 9993cfb commit 5dd693d

File tree

9 files changed

+355
-3
lines changed

9 files changed

+355
-3
lines changed

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
.psci
2+
.psci_modules/
13
node_modules
24
bower_components
3-
js
4-
externs
55
dist
6-
output
76
tmp

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2014 Eric Thul
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a
4+
copy of this software and associated documentation files (the
5+
"Software"), in the Software without restriction, including without
6+
limitation the rights to use, copy, modify, merge, publish, distribute,
7+
sublicense, and/or sell copies of the Software, and to permit persons to
8+
whom the Software is furnished to do so, subject to the following
9+
conditions:
10+
11+
The above copyright notice and this permission notice shall be included
12+
in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Module Documentation
2+
3+
## Module Data.Coyoneda
4+
5+
### Types
6+
7+
newtype Coyoneda f a where
8+
Coyoneda :: forall i. { fi :: f i, k :: i -> a } -> Coyoneda f a
9+
10+
type Natural f g = forall a. f a -> g a
11+
12+
13+
### Type Class Instances
14+
15+
instance applicativeCoyoneda :: (Applicative f) => Applicative (Coyoneda f)
16+
17+
instance applyCoyoneda :: (Apply f) => Apply (Coyoneda f)
18+
19+
instance bindCoyoneda :: (Bind f) => Bind (Coyoneda f)
20+
21+
instance comonadCoyoneda :: (Comonad w) => Comonad (Coyoneda w)
22+
23+
instance extendCoyoneda :: (Extend w) => Extend (Coyoneda w)
24+
25+
instance functorCoyoneda :: Functor (Coyoneda f)
26+
27+
instance monadCoyoneda :: (Monad f) => Monad (Coyoneda f)
28+
29+
instance monadTransCoyoneda :: MonadTrans Coyoneda
30+
31+
32+
### Values
33+
34+
coyoneda :: forall f a b. (a -> b) -> f a -> Coyoneda f b
35+
36+
liftCoyoneda :: forall f a. f a -> Coyoneda f a
37+
38+
liftCoyonedaT :: forall f g. Natural f g -> Natural (Coyoneda f) (Coyoneda g)
39+
40+
liftCoyonedaTF :: forall f g. (Functor g) => Natural f g -> Natural (Coyoneda f) g
41+
42+
lowerCoyoneda :: forall f a. (Functor f) => Coyoneda f a -> f a
43+
44+
45+
## Module Data.Yoneda
46+
47+
### Types
48+
49+
newtype Yoneda f a where
50+
Yoneda :: forall b. (a -> b) -> f b -> Yoneda f a
51+
52+
53+
### Type Class Instances
54+
55+
instance applicativeYoneda :: (Applicative f) => Applicative (Yoneda f)
56+
57+
instance applyYoneda :: (Apply f) => Apply (Yoneda f)
58+
59+
instance bindCoyoneda :: (Bind f) => Bind (Yoneda f)
60+
61+
instance comonadYoneda :: (Comonad w) => Comonad (Yoneda w)
62+
63+
instance extendYoneda :: (Extend w) => Extend (Yoneda w)
64+
65+
instance functorYoneda :: Functor (Yoneda f)
66+
67+
instance monadTransYoneda :: MonadTrans Yoneda
68+
69+
instance monadYoneda :: (Monad f) => Monad (Yoneda f)
70+
71+
72+
### Values
73+
74+
liftYoneda :: forall f a. (Functor f) => f a -> Yoneda f a
75+
76+
lowerYoneda :: forall f a. Yoneda f a -> f a
77+
78+
runYoneda :: forall f a b. Yoneda f a -> (a -> b) -> f b
79+
80+
81+

bower.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "purescript-yoneda",
3+
"version": "0.0.0",
4+
"homepage": "https://github.com/ethul/purescript-yoneda",
5+
"description": "Yoneda/Coyoneda",
6+
"keywords": [
7+
"purescript"
8+
],
9+
"license": "MIT",
10+
"ignore": [
11+
"**/.*",
12+
"node_modules",
13+
"bower_components",
14+
"examples",
15+
"dist"
16+
],
17+
"dependencies": {
18+
"purescript-control": "0.2.1",
19+
"purescript-transformers": "0.1.1"
20+
}
21+
}

examples/Teletype.purs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module Teletype where
2+
3+
import Control.Monad.Eff
4+
import Control.Monad.Free
5+
import Data.Coyoneda
6+
import Debug.Trace
7+
8+
type FreeC f a = Free (Coyoneda f) a
9+
10+
data TeletypeF a = PutStrLn String a | GetLine (String -> a)
11+
12+
type Teletype a = FreeC TeletypeF a
13+
14+
type TeletypeC a = Coyoneda TeletypeF a
15+
16+
putStrLn :: String -> Teletype Unit
17+
putStrLn s = liftF $ liftCoyoneda $ PutStrLn s unit
18+
19+
getLine :: Teletype String
20+
getLine = liftF $ liftCoyoneda $ GetLine id
21+
22+
teletypeNat :: forall e. Natural TeletypeF (Eff (trace :: Trace))
23+
teletypeNat (PutStrLn s a) = (\_ -> a) <$> trace s
24+
teletypeNat (GetLine k) = return $ k "fake input"
25+
26+
run :: forall a. Teletype a -> Eff (trace :: Trace) a
27+
run = goEff (liftCoyonedaTF teletypeNat)
28+
29+
echo = do
30+
a <- getLine
31+
putStrLn a
32+
putStrLn "Finished"
33+
return $ a ++ a
34+
35+
main = do
36+
a <- run $ echo
37+
trace a

gulpfile.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
var gulp = require('gulp')
2+
, clean = require('gulp-clean')
3+
, gutil = require('gulp-util')
4+
, plumber = require('gulp-plumber')
5+
, purescript = require('gulp-purescript')
6+
, sequence = require('run-sequence')
7+
, config = {
8+
clean: ['dist', 'js', 'externs'],
9+
purescript: {
10+
src: [
11+
'bower_components/purescript-*/src/**/*.purs*',
12+
'src/**/*.purs'
13+
],
14+
examples: 'examples/**/*.purs',
15+
docgen: 'README.md',
16+
dest: 'dist',
17+
options: {
18+
main: 'Teletype'
19+
}
20+
}
21+
}
22+
;
23+
24+
function error(e) {
25+
gutil.log(gutil.colors.magenta('>>>> Error <<<<') + '\n' + e.toString().trim());
26+
this.emit('end');
27+
}
28+
29+
gulp.task('clean', function(){
30+
return (
31+
gulp.src(config.clean, {read: false}).
32+
pipe(clean())
33+
);
34+
});
35+
36+
gulp.task('examples', function(){
37+
return (
38+
gulp.src([config.purescript.examples].concat(config.purescript.src)).
39+
pipe(plumber()).
40+
pipe(purescript.psc(config.purescript.options)).
41+
on('error', error).
42+
pipe(gulp.dest(config.purescript.dest))
43+
);
44+
});
45+
46+
gulp.task('make', function(){
47+
return (
48+
gulp.src(config.purescript.src).
49+
pipe(plumber()).
50+
pipe(purescript.pscMake({output: config.purescript.dest})).
51+
on('error', error)
52+
);
53+
});
54+
55+
gulp.task('psci', function(){
56+
return (
57+
gulp.src(config.purescript.src).
58+
pipe(plumber()).
59+
pipe(purescript.dotPsci()).
60+
on('error', error)
61+
);
62+
});
63+
64+
gulp.task('docgen', function(){
65+
return (
66+
gulp.src(config.purescript.src[1]).
67+
pipe(plumber()).
68+
pipe(purescript.docgen()).
69+
on('error', error).
70+
pipe(gulp.dest(config.purescript.docgen))
71+
);
72+
});
73+
74+
gulp.task('watch', function(cb){
75+
gulp.watch(config.purescript.src, ['make']);
76+
});
77+
78+
gulp.task('default', function(){
79+
sequence('clean', 'make', ['psci', 'docgen']);
80+
});

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "purescript-kan",
3+
"private": true,
4+
"devDependencies": {
5+
"gulp": "3.8.7",
6+
"gulp-clean": "0.2.4",
7+
"gulp-plumber": "0.5.6",
8+
"gulp-purescript": "0.0.10",
9+
"gulp-util": "2.2.14",
10+
"run-sequence": "0.3.6"
11+
}
12+
}

src/Data/Coyoneda.purs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module Data.Coyoneda
2+
( Coyoneda(..)
3+
, Natural(..)
4+
, coyoneda
5+
, liftCoyoneda
6+
, lowerCoyoneda
7+
, liftCoyonedaT
8+
, liftCoyonedaTF
9+
) where
10+
11+
import Control.Comonad
12+
import Control.Extend
13+
import Control.Monad.Trans
14+
import Data.Tuple
15+
16+
newtype Coyoneda f a = Coyoneda (forall i. { k :: i -> a , fi :: f i })
17+
18+
type Natural f g = forall a. f a -> g a
19+
20+
instance functorCoyoneda :: Functor (Coyoneda f) where
21+
(<$>) f (Coyoneda v) = Coyoneda v { k = f <<< v.k }
22+
23+
instance applyCoyoneda :: (Apply f) => Apply (Coyoneda f) where
24+
(<*>) f g = liftCoyoneda $ lowerCoyoneda f <*> lowerCoyoneda g
25+
26+
instance applicativeCoyoneda :: (Applicative f) => Applicative (Coyoneda f) where
27+
pure = liftCoyoneda <<< pure
28+
29+
instance bindCoyoneda :: (Bind f) => Bind (Coyoneda f) where
30+
(>>=) (Coyoneda v) k = liftCoyoneda $ v.fi >>= lowerCoyoneda <<< k <<< v.k
31+
32+
instance monadCoyoneda :: (Monad f) => Monad (Coyoneda f)
33+
34+
instance monadTransCoyoneda :: MonadTrans Coyoneda where
35+
lift = liftCoyoneda
36+
37+
instance extendCoyoneda :: (Extend w) => Extend (Coyoneda w) where
38+
(<<=) f (Coyoneda w) = liftCoyoneda $ f <<< coyoneda w.k <<= w.fi
39+
40+
instance comonadCoyoneda :: (Comonad w) => Comonad (Coyoneda w) where
41+
extract (Coyoneda w) = w.k $ extract w.fi
42+
43+
coyoneda :: forall f a b. (a -> b) -> f a -> Coyoneda f b
44+
coyoneda k fi = k <$> liftCoyoneda fi
45+
46+
--liftCoyoneda :: forall f a. f a -> Coyoneda f a
47+
--liftCoyoneda fa = Coyoneda { k: id , fi: fa }
48+
foreign import liftCoyoneda "function liftCoyoneda(fa){return {k: function(a){return a;}, fi: fa};}"
49+
:: forall f a. f a -> Coyoneda f a
50+
51+
lowerCoyoneda :: forall f a. (Functor f) => Coyoneda f a -> f a
52+
lowerCoyoneda (Coyoneda v) = v.k <$> v.fi
53+
54+
liftCoyonedaT :: forall f g. Natural f g -> Natural (Coyoneda f) (Coyoneda g)
55+
liftCoyonedaT nat = \(Coyoneda v) -> Coyoneda v { fi = nat v.fi }
56+
57+
liftCoyonedaTF :: forall f g. (Functor g) => Natural f g -> Natural (Coyoneda f) g
58+
liftCoyonedaTF nat = lowerCoyoneda <<< liftCoyonedaT nat

src/Data/Yoneda.purs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module Data.Yoneda
2+
( Yoneda(..)
3+
, runYoneda
4+
, liftYoneda
5+
, lowerYoneda
6+
) where
7+
8+
import Control.Comonad
9+
import Control.Extend
10+
import Control.Monad.Trans
11+
12+
newtype Yoneda f a = Yoneda (forall b. (a -> b) -> f b)
13+
14+
instance functorYoneda :: Functor (Yoneda f) where
15+
(<$>) f m = Yoneda (\k -> runYoneda m (k <<< f))
16+
17+
instance applyYoneda :: (Apply f) => Apply (Yoneda f) where
18+
(<*>) (Yoneda f) (Yoneda g) = Yoneda (\k -> (f $ (<<<) k) <*> g id)
19+
20+
instance applicativeYoneda :: (Applicative f) => Applicative (Yoneda f) where
21+
pure = liftYoneda <<< pure
22+
23+
instance bindCoyoneda :: (Bind f) => Bind (Yoneda f) where
24+
(>>=) (Yoneda f) g = Yoneda (\k -> f id >>= \a -> runYoneda (g a) k)
25+
26+
instance monadYoneda :: (Monad f) => Monad (Yoneda f)
27+
28+
instance monadTransYoneda :: MonadTrans Yoneda where
29+
lift = liftYoneda
30+
31+
instance extendYoneda :: (Extend w) => Extend (Yoneda w) where
32+
(<<=) f (Yoneda w) = Yoneda (\k -> k <<< f <<< liftYoneda <<= w id)
33+
34+
instance comonadYoneda :: (Comonad w) => Comonad (Yoneda w) where
35+
extract = extract <<< lowerYoneda
36+
37+
runYoneda :: forall f a b. Yoneda f a -> (a -> b) -> f b
38+
runYoneda (Yoneda f) k = f k
39+
40+
liftYoneda :: forall f a. (Functor f) => f a -> Yoneda f a
41+
liftYoneda m = Yoneda (\k -> k <$> m)
42+
43+
lowerYoneda :: forall f a. Yoneda f a -> f a
44+
lowerYoneda (Yoneda k) = k id

0 commit comments

Comments
 (0)