Skip to content

Commit 8444156

Browse files
committed
Merge branch 'master' into infix
2 parents 5009ad0 + 19891d6 commit 8444156

9 files changed

+98
-203
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ rebar3
1313
rebar.lock
1414
_build/
1515
*.sublime-*
16+
t.erl
17+

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The [feature overview](doc/features.md) provides an introduction to datum featur
2020
* data structures with common behavior: **foldable**, **traversable** and **map-like** including
2121
* pure functional **data types**: binary search tree, red-black tree, heap, queues, streams and others
2222
* resembles concept of getters and setters ([**lens**](doc/lens.md)) for complex algebraic data types.
23-
* define a **category pattern** and **monads**
23+
* define a **category pattern**, **monads** and **do-notation** with pattern matching
2424
* [type casts](doc/typecast.md) of scalar (primitive) data types
2525
* supports **OTP/18.x** or later release
2626

doc/category.md

+11
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,17 @@ f(X, Y, R) ->
111111

112112
The usage of intermediate state do not benefit for chains of ordinary functions. Unfortunately, we can't express all of our programs as chains of ordinary functions. Later' we will demonstrate the benefit of intermediate states for computation with a side-effect.
113113

114+
Note: the state syntax supports a traditional pattern matching but it is not available for identity and undefined categories yet.
115+
116+
> In a pattern matching, a left-hand side pattern is matched against a right-hand side term. If the matching succeeds, any unbound variables in the pattern become bound. If the matching fails, a run-time error occurs.
117+
```erlang
118+
f(X, Y, R) ->
119+
[either ||
120+
...
121+
{fd, Data} <- read(...)
122+
...
123+
].
124+
```
114125

115126
### Composition with transformers
116127

src/category/datum_cat_either.erl

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@
2424
%%
2525
'.'(_, {either, VarX, G}, {call, Ln, Ff0, Fa0}) ->
2626
{Fa1, VarN} = datum_cat:cc_derive(Fa0, []),
27-
Expr = dot_expr(Ln, VarX, {call, Ln, Ff0, Fa1}, G),
27+
Pattern = [{var, Ln, X} || X <- VarX],
28+
Expr = dot_expr(Ln, Pattern, {call, Ln, Ff0, Fa1}, G),
2829
{either, VarN, Expr};
2930

30-
'.'(_, {either, _VarX, G}, {generate, Ln, {var, _, VarN}, F}) ->
31+
'.'(_, {either, _VarX, G}, {generate, Ln, Pattern, F}) ->
3132
{Fa1, VarZ} = datum_cat:cc_derive(F, []),
32-
Expr = dot_expr(Ln, [VarN], Fa1, G),
33+
Expr = dot_expr(Ln, [Pattern], Fa1, G),
3334
{either, VarZ, Expr};
3435

3536
'.'(Cat, {call, Ln, Ff0, Fa0}, G) ->
@@ -57,12 +58,11 @@ dot_expr(Ln, [], F, G) ->
5758
[G]
5859
}
5960
]};
60-
dot_expr(Ln, VarX, F, G) ->
61+
dot_expr(Ln, Pattern, F, G) ->
6162
Err = datum_cat:uuid(),
62-
Pat = [{var, Ln, X} || X <- VarX],
6363
{'case', Ln, F, [
6464
{clause, Ln,
65-
[{tuple, Ln, [{atom, Ln, ok}|Pat]}],
65+
[{tuple, Ln, [{atom, Ln, ok}|Pattern]}],
6666
[],
6767
[G]
6868
},

src/category/datum_cat_kleisli.erl

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@
1919
%%
2020
%% f(_) . g(_) -> m_state:'>>='(f(), fun(X) -> m_state:'>>='(g(X), ...) end)
2121
'.'(Monad, {monad, VarX, G}, {call, Ln, Ff0, Fa0}) ->
22-
VarN = datum_cat:uuid(),
23-
Expr = dot_expr(Monad, Ln, VarX, {call, Ln, Ff0, datum_cat:cc_bind_var({var, Ln, VarN}, Fa0)}, G),
22+
VarN = {var, Ln, datum_cat:uuid()},
23+
Expr = dot_expr(Monad, Ln, VarX, {call, Ln, Ff0, datum_cat:cc_bind_var(VarN, Fa0)}, G),
2424
{monad, VarN, Expr};
2525

26-
'.'(Monad, {monad, VarX, G}, {generate, Ln, {var, _, VarN}, F}) ->
27-
Expr = dot_expr(Monad, Ln, VarN, datum_cat:cc_bind_var({var, Ln, VarX}, F), G),
26+
'.'(Monad, {monad, VarX, G}, {generate, Ln, Pattern, F}) ->
27+
Expr = dot_expr(Monad, Ln, Pattern, datum_cat:cc_bind_var(VarX, F), G),
2828
{monad, VarX, Expr};
2929

3030
'.'(Monad, {call, Ln, _, _} = F, G) ->
31-
VarN = datum_cat:uuid(),
32-
Expr = {call, Ln, {remote, Ln, {atom, Ln, Monad}, {atom, Ln, unit}}, [{var, Ln, VarN}]},
31+
VarN = {var, Ln, datum_cat:uuid()},
32+
Expr = {call, Ln, {remote, Ln, {atom, Ln, Monad}, {atom, Ln, unit}}, [VarN]},
3333
'.'(Monad, '.'(Monad, {monad, VarN, Expr}, F), G);
3434

3535
'.'(Cat, {generate, _Ln, _Var, F}, G) ->
@@ -38,15 +38,15 @@
3838

3939
%%
4040
%%
41-
dot_expr(Monad, Ln, VarX, F, G) ->
41+
dot_expr(Monad, Ln, Pattern, F, G) ->
4242
{call, Ln,
4343
{remote, Ln, {atom, Ln, Monad}, {atom, Ln, '>>='}},
4444
[
4545
F,
4646
{'fun', Ln,
4747
{clauses,
4848
[
49-
{clause, Ln, [{var, Ln, VarX}], [], [G]}
49+
{clause, Ln, [Pattern], [], [G]}
5050
]
5151
}
5252
}
@@ -65,7 +65,7 @@ curry({monad, VarX, {_, Ln, _, _} = Expr}) ->
6565
{'fun', Ln,
6666
{clauses, [
6767
{clause, Ln,
68-
[{var, Ln, VarX}],
68+
[VarX],
6969
[],
7070
[Expr]
7171
}

src/category/datum_cat_option.erl

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@
2222
%% f(_) . g(_) -> case f(_) of undefined -> undefined ; X -> g(X) end
2323
%%
2424
'.'(_, {option, VarX, G}, {call, Ln, Ff0, Fa0}) ->
25-
VarN = datum_cat:uuid(),
26-
Expr = dot_expr(Ln, VarX, {call, Ln, Ff0, datum_cat:cc_bind_var({var, Ln, VarN}, Fa0)}, G),
25+
VarN = {var, Ln, datum_cat:uuid()},
26+
Expr = dot_expr(Ln, VarX, {call, Ln, Ff0, datum_cat:cc_bind_var(VarN, Fa0)}, G),
2727
{option, VarN, Expr};
2828

29-
'.'(_, {option, VarX, G}, {generate, Ln, {var, _, VarN}, F}) ->
30-
Expr = dot_expr(Ln, VarN, datum_cat:cc_bind_var({var, Ln, VarX}, F), G),
29+
'.'(_, {option, VarX, G}, {generate, Ln, Pattern, F}) ->
30+
Expr = dot_expr(Ln, Pattern, datum_cat:cc_bind_var(VarX, F), G),
3131
{option, VarX, Expr};
3232

3333
'.'(Cat, {call, Ln, Ff0, Fa0}, G) ->
34-
VarN = datum_cat:uuid(),
35-
Expr = {call, Ln, Ff0, datum_cat:cc_bind_var({var, Ln, VarN}, Fa0)},
34+
VarN = {var, Ln, datum_cat:uuid()},
35+
Expr = {call, Ln, Ff0, datum_cat:cc_bind_var(VarN, Fa0)},
3636
'.'(Cat, {option, VarN, Expr}, G);
3737

3838
'.'(Cat, {generate, _Ln, _Var, F}, G) ->
@@ -41,15 +41,15 @@
4141

4242
%%
4343
%%
44-
dot_expr(Ln, VarX, F, G) ->
44+
dot_expr(Ln, Pattern, F, G) ->
4545
{'case', Ln, F, [
4646
{clause, Ln,
4747
[{atom, Ln, undefined}],
4848
[],
4949
[{atom, Ln, undefined}]
5050
},
5151
{clause, Ln,
52-
[{var, Ln, VarX}],
52+
[Pattern],
5353
[],
5454
[G]
5555
}
@@ -66,7 +66,7 @@ curry({option, VarX, {'case', Ln, _, _} = Expr}) ->
6666
{'fun', Ln,
6767
{clauses, [
6868
{clause, Ln,
69-
[{var, Ln, VarX}],
69+
[VarX],
7070
[],
7171
[Expr]
7272
}

src/category/datum_cat_reader.erl

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@
2626
%%
2727
'.'(_, {either, VarX, G}, {call, Ln, Ff0, Fa0}) ->
2828
{Fa1, VarN} = datum_cat:cc_derive(Fa0, []),
29-
Expr = dot_expr(Ln, VarX, {call, Ln, Ff0, Fa1}, G),
29+
Pattern = [{var, Ln, X} || X <- VarX],
30+
Expr = dot_expr(Ln, Pattern, {call, Ln, Ff0, Fa1}, G),
3031
{either, VarN, Expr};
3132

32-
'.'(_, {either, _VarX, G}, {generate, Ln, {var, _, VarN}, F}) ->
33+
'.'(_, {either, _VarX, G}, {generate, Ln, Pattern, F}) ->
3334
{Fa1, VarZ} = datum_cat:cc_derive(F, []),
34-
Expr = dot_expr(Ln, [VarN], Fa1, G),
35+
Expr = dot_expr(Ln, [Pattern], Fa1, G),
3536
{either, VarZ, Expr};
3637

3738
'.'(Cat, {call, Ln, Ff0, Fa0}, G) ->
@@ -58,12 +59,11 @@ dot_expr(Ln, [], F, G) ->
5859
[G]
5960
}
6061
]};
61-
dot_expr(Ln, VarX, F, G) ->
62+
dot_expr(Ln, Pattern, F, G) ->
6263
Err = datum_cat:uuid(),
63-
Pat = [{var, Ln, X} || X <- VarX],
6464
{'case', Ln, F, [
6565
{clause, Ln,
66-
[{tuple, Ln, [{atom, Ln, ok}|Pat]}],
66+
[{tuple, Ln, [{atom, Ln, ok}|Pattern]}],
6767
[],
6868
[G]
6969
},

0 commit comments

Comments
 (0)