Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit 6ef7f81

Browse files
committed
Get tests running
Also started laws. We need to do `Prism` laws as well. I'm not sure how to formulate them without using functions from `purescript-optic`. This will require some thinking.
1 parent 54744ab commit 6ef7f81

File tree

5 files changed

+123
-53
lines changed

5 files changed

+123
-53
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"purescript-either": "~0.2.0",
3030
"purescript-identity": "~0.4.0",
3131
"purescript-maybe": "~0.3.2",
32-
"purescript-profunctor": "~0.3.0"
32+
"purescript-profunctor": "~0.3.0",
33+
"purescript-console": "~0.1.0"
3334
}
3435
}

docs/Optic/Laws/Lens.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Module Optic.Laws.Lens
2+
3+
Valid `Lens`es should satisfy three laws.
4+
5+
#### `getSet`
6+
7+
``` purescript
8+
getSet :: forall s a. (Eq s) => LensP s a -> s -> Boolean
9+
```
10+
11+
If you get a value out, and then set it immediately back,
12+
nothing should change.
13+
14+
#### `setGet`
15+
16+
``` purescript
17+
setGet :: forall s a. (Eq a) => LensP s a -> s -> a -> Boolean
18+
```
19+
20+
If you set a value, and them get it immediately out,
21+
you should get the value you set.
22+
23+
#### `setSet`
24+
25+
``` purescript
26+
setSet :: forall s a b. (Eq s) => Lens s s a b -> s -> b -> b -> Boolean
27+
```
28+
29+
If you set two values, the last set is the one that matters.
30+
31+

gulpfile.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ var paths =
2121
, 'Optic.Getter': 'docs/Optic/Getter.md'
2222
, 'Optic.Internal.Prism': 'docs/Optic/Internal/Prism.md'
2323
, 'Optic.Internal.Setter': 'docs/Optic/Internal/Setter.md'
24+
, 'Optic.Laws.Lens': 'docs/Optic/Laws/Lens.md'
2425
, 'Optic.Lens': 'docs/Optic/Lens.md'
2526
, 'Optic.Prism': 'docs/Optic/Prism.md'
2627
, 'Optic.Setter': 'docs/Optic/Setter.md'
2728
, 'Optic.Types': 'docs/Optic/Types.md'
2829
}
30+
, outputJs: 'output/**/*.js'
2931
, test: 'test/**/*.purs'
3032
};
3133

3234
var options =
33-
{ test: { main: 'Test.Optic'
35+
{ test: { main: 'Test.Main'
3436
}
3537
};
3638

@@ -72,8 +74,22 @@ gulp.task('docs', function() {
7274
});
7375
});
7476

77+
gulp.task('test-compile', function() {
78+
return purescript.psc({
79+
src: paths.bowerSrc.concat(paths.src, paths.test),
80+
ffi: paths.bowerFFIJs
81+
});
82+
});
83+
84+
gulp.task('test', ['test-compile'], function() {
85+
return purescript.pscBundle({
86+
src: paths.outputJs,
87+
main: options.test.main
88+
}).pipe(run('node'));
89+
});
90+
7591
gulp.task('watch', function() {
76-
gulp.watch(paths.src, function() {runSequence('psc', 'docs')});
92+
gulp.watch([paths.src, paths.test], function() {runSequence('psc', 'test', 'docs')});
7793
});
7894

79-
gulp.task('default', function() {runSequence('psc', 'docs')});
95+
gulp.task('default', function() {runSequence('psc', 'test', 'docs')});

src/Optic/Laws/Lens.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- | Valid `Lens`es should satisfy three laws.
2+
module Optic.Laws.Lens where
3+
4+
import Optic.Getter (view)
5+
import Optic.Setter (set)
6+
import Optic.Types (Lens(), LensP())
7+
8+
import Prelude (Eq, (==))
9+
10+
-- | If you get a value out, and then set it immediately back,
11+
-- | nothing should change.
12+
getSet :: forall s a. (Eq s) => LensP s a -> s -> Boolean
13+
getSet l s = set l (view l s) s == s
14+
15+
-- | If you set a value, and them get it immediately out,
16+
-- | you should get the value you set.
17+
setGet :: forall s a. (Eq a) => LensP s a -> s -> a -> Boolean
18+
setGet l s x = view l (set l x s) == x
19+
20+
-- | If you set two values, the last set is the one that matters.
21+
setSet :: forall s a b. (Eq s) => Lens s s a b -> s -> b -> b -> Boolean
22+
setSet l s x y = set l y (set l x s) == set l y s

test/Main.purs

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
module Test.Main where
22

3-
import Prelude
4-
import Optic.Core
5-
import Control.Monad.Eff.Console
6-
7-
newtype Foo bar baz = Foo
8-
{ foo :: { bar :: bar }
9-
, baz :: baz
10-
}
11-
12-
instance showFoo :: (Show bar, Show baz) => Show (Foo bar baz) where
13-
show (Foo x) = "(Foo " ++ show x.foo.bar ++ " " ++ show x.baz ++ ")"
14-
15-
_Foo :: forall bar1 baz1 bar2 baz2.
16-
Lens (Foo bar1 baz1)
17-
(Foo bar2 baz2)
18-
{ baz :: baz1, foo :: { bar :: bar1 } }
19-
{ baz :: baz2, foo :: { bar :: bar2 } }
20-
_Foo = lens (\(Foo x) -> x) (const Foo)
21-
22-
foo :: forall a b r. Lens { foo :: a | r } { foo :: b | r } a b
23-
foo = lens _.foo (_ { foo = _ })
24-
25-
foo' :: forall a b r. Lens { foo :: a | r } { foo :: b | r } a b
26-
foo' = foo
27-
28-
bar :: forall a b r. Lens { bar :: a | r } { bar :: b | r } a b
29-
bar = lens _.bar (_ { bar = _ })
30-
31-
baz :: forall a b r. Lens { baz :: a | r } { baz :: b | r } a b
32-
baz = lens _.baz (_ { baz = _ })
33-
34-
fooBar :: forall a b r r'. Lens { foo :: { bar :: a | r } | r' } { foo :: { bar :: b | r } | r' } a b
35-
fooBar = foo..bar
36-
37-
obj :: Foo Int Boolean
38-
obj = Foo { foo: { bar: 0 }, baz: true }
39-
40-
succ :: Int -> Int
41-
succ x = x + 1
42-
43-
main = do
44-
print obj -- (Foo 0 true)
45-
print $ _Foo..baz .~ 10 $ obj -- (Foo 0 10)
46-
print $ _Foo..baz .~ "wat" $ obj -- (Foo 0 "wat")
47-
print $ _Foo..foo'..bar .~ 10 $ obj -- (Foo 10 true)
48-
print $ _Foo..fooBar +~ 40 $ obj -- (Foo 40 true)
49-
print $ obj ^. _Foo..fooBar -- 0
50-
print $ obj # _Foo..fooBar %~ succ -- (Foo 1 true)
51-
print $ over (_Foo..fooBar) succ obj -- (Foo 1 true)
3+
import Prelude (Show, (#), ($), (+), (++), bind, const, show)
4+
import Optic.Core
5+
import Control.Monad.Eff.Console (print)
6+
7+
newtype Foo bar baz = Foo
8+
{ foo :: { bar :: bar }
9+
, baz :: baz
10+
}
11+
12+
instance showFoo :: (Show bar, Show baz) => Show (Foo bar baz) where
13+
show (Foo x) = "(Foo " ++ show x.foo.bar ++ " " ++ show x.baz ++ ")"
14+
15+
_Foo :: forall bar1 baz1 bar2 baz2.
16+
Lens (Foo bar1 baz1)
17+
(Foo bar2 baz2)
18+
{ baz :: baz1, foo :: { bar :: bar1 } }
19+
{ baz :: baz2, foo :: { bar :: bar2 } }
20+
_Foo = lens (\(Foo x) -> x) (const Foo)
21+
22+
foo :: forall a b r. Lens { foo :: a | r } { foo :: b | r } a b
23+
foo = lens _.foo (_ { foo = _ })
24+
25+
foo' :: forall a b r. Lens { foo :: a | r } { foo :: b | r } a b
26+
foo' = foo
27+
28+
bar :: forall a b r. Lens { bar :: a | r } { bar :: b | r } a b
29+
bar = lens _.bar (_ { bar = _ })
30+
31+
baz :: forall a b r. Lens { baz :: a | r } { baz :: b | r } a b
32+
baz = lens _.baz (_ { baz = _ })
33+
34+
fooBar :: forall a b r r'. Lens { foo :: { bar :: a | r } | r' } { foo :: { bar :: b | r } | r' } a b
35+
fooBar = foo..bar
36+
37+
obj :: Foo Int Boolean
38+
obj = Foo { foo: { bar: 0 }, baz: true }
39+
40+
succ :: Int -> Int
41+
succ x = x + 1
42+
43+
main = do
44+
print obj -- (Foo 0 true)
45+
print $ _Foo..baz .~ 10 $ obj -- (Foo 0 10)
46+
print $ _Foo..baz .~ "wat" $ obj -- (Foo 0 "wat")
47+
print $ _Foo..foo'..bar .~ 10 $ obj -- (Foo 10 true)
48+
print $ _Foo..fooBar +~ 40 $ obj -- (Foo 40 true)
49+
print $ obj ^. _Foo..fooBar -- 0
50+
print $ obj # _Foo..fooBar %~ succ -- (Foo 1 true)
51+
print $ over (_Foo..fooBar) succ obj -- (Foo 1 true)

0 commit comments

Comments
 (0)