Skip to content

Commit 4752d26

Browse files
committed
currying, id, const, fix, Lazy, Reader, Unit, FunHandle and friends
1 parent 800e717 commit 4752d26

34 files changed

+358
-43
lines changed

+Control/+Monad/+Lazy/Lazy.m

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
% Lazy monad for epic laziness
2+
3+
% Lazy :: * -> *
4+
classdef Lazy < handle & Control.Monad.Monad
5+
properties (GetAccess = private, SetAccess = private)
6+
% d_thunk :: a
7+
d_thunk
8+
end
9+
10+
methods (Access = private)
11+
% Lazy :: a -> Lazy a
12+
function instance = Lazy (thunk)
13+
instance.d_thunk = thunk;
14+
end
15+
end
16+
17+
methods
18+
% bind :: ({Lazy a}, (a -> Lazy b)) -> Lazy b
19+
function result = bind (this, fun)
20+
result = Control.Monad.Lazy.Lazy (@bind_);
21+
function res = bind_ ()
22+
inter = fun (this.evalLazy ());
23+
res = inter.evalLazy ();
24+
end
25+
end
26+
27+
% strictly evaluate the monad
28+
% evalLazy :: Lazy a -> a
29+
function result = evalLazy (this)
30+
result = this.d_thunk ();
31+
end
32+
end
33+
34+
methods (Static)
35+
% mreturn :: a -> Lazy a
36+
function result = mreturn (value)
37+
result = Control.Monad.Lazy.Lazy (@mreturn_);
38+
function res = mreturn_ ()
39+
res = value;
40+
end
41+
end
42+
end
43+
end

+Control/+Monad/+Reader/Reader.m

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
classdef Reader < handle & Control.Monad.Monad
2+
3+
properties (GetAccess = private, SetAccess = private)
4+
d_runReader
5+
end
6+
7+
methods (Access = private)
8+
function instance = Reader (runReader)
9+
instance.d_runReader = runReader;
10+
end
11+
end
12+
13+
methods (Static)
14+
function result = mreturn (value)
15+
result = Reader (const (value));
16+
end
17+
end
18+
19+
methods
20+
function result = ask ()
21+
result = Reader (id);
22+
end
23+
24+
function result = runReader (this, r)
25+
result = this.d_runReader (r);
26+
end
27+
28+
% (r -> a) -> (a -> r -> b) -> (r -> b)
29+
function result = bind (this, fun)
30+
result = Reader (@bindFun);
31+
function res = bindFun (r)
32+
a = this.runReader (r);
33+
rb = fun (a);
34+
res = rb.runReader (r);
35+
end
36+
end
37+
end
38+
end
39+

+Control/+Monad/Monad.m

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
% (Monad m) => m :: * -> *
2+
classdef Monad < handle
3+
4+
methods (Abstract)
5+
% bind :: ({m a}, (a -> m b)) -> m b
6+
result = bind (fun)
7+
end
8+
9+
methods (Static, Abstract)
10+
% mreturn :: a -> m a
11+
result = mreturn (value)
12+
end
13+
14+
methods
15+
% >= overload for bind
16+
function result = ge (this, fun)
17+
result = this.bind (fun);
18+
end
19+
end
20+
21+
methods (Static)
22+
% liftM :: (a -> b) -> (m a -> m b)
23+
function result = liftM (f)
24+
result = Data.FunHandle.lambda1 (@liftM_);
25+
function res = liftM_ (ma)
26+
res = ma >= (@(a) mreturn (f (a)));
27+
end
28+
end
29+
end
30+
end

+Data/+BinTree/BinTree.m

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
methods (Abstract)
44
% Functor instance
5-
result = fmap (fun)
6-
m_fmap (fun)
5+
result = fmap_ (fun)
6+
m_fmap_ (fun)
77

88
% folds the tree using two handles
99
result = fold (branchFunction, leafFunction)

+Data/+BinTree/BinTreeBranch.m

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
classdef BinTreeBranch < Data.BinTree.BinTree
22

3-
properties (SetAccess = private)
3+
properties (GetAccess = private, SetAccess = private)
44
d_branchValue
55
d_left
66
d_right
@@ -13,17 +13,17 @@
1313
instance.d_right = rightTree;
1414
end
1515

16-
function result = fmap (this, fun)
17-
left = this.d_left.fmap (fun);
18-
right = this.d_right.fmap (fun);
16+
function result = fmap_ (this, fun)
17+
left = this.d_left.fmap_ (fun);
18+
right = this.d_right.fmap_ (fun);
1919
value = fun (this.d_branchValue);
2020
result = Data.BinTree.BinTreeBranch (value, left, right);
2121
end
2222

23-
function m_fmap (this, fun)
23+
function m_fmap_ (this, fun)
2424
this.d_branchValue = fun (this.d_branchValue);
25-
this.d_left.m_fmap (fun);
26-
this.d_right.m_fmap (fun);
25+
this.d_left.m_fmap_ (fun);
26+
this.d_right.m_fmap_ (fun);
2727
end
2828

2929
function result = fold (this, branchFunction, leafFunction)

+Data/+BinTree/BinTreeLeaf.m

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
classdef BinTreeLeaf < Data.BinTree.BinTree
22

3-
properties (SetAccess = private)
3+
properties (GetAccess = private, SetAccess = private)
44
d_leafValue
55
end
66

@@ -9,12 +9,12 @@
99
instance.d_leafValue = value;
1010
end
1111

12-
function result = fmap (this, fun)
12+
function result = fmap_ (this, fun)
1313
result = Data.BinTree.BinTreeLeaf (fun ...
1414
(this.d_leafValue));
1515
end
1616

17-
function m_fmap (this, fun)
17+
function m_fmap_ (this, fun)
1818
end
1919

2020
function result = fold (this, branchFunction, leafFunction)

+Data/+FunHandle/FunHandle.m

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
% a wrapper around a function handle so we can do funky stuff
2+
classdef FunHandle < handle
3+
4+
properties %(GetAccess = private, SetAccess = private)
5+
d_funHandle
6+
end
7+
8+
methods
9+
% (a -> b) -> FunHandle (a -> b)
10+
function instance = FunHandle (lambda1)
11+
instance.d_funHandle = lambda1;
12+
end
13+
14+
% function application operator so we can treat it the same
15+
% as an actual handle
16+
% subsindex :: ({FunHandle (a -> b)}, a) -> b
17+
function result = subsref (this, val)
18+
result = this.d_funHandle (val.subs{1});
19+
end
20+
21+
% "times" so we can simulate fun(a)(b)(c) with fun*a*b*c,
22+
% freakin matlab parser cant do ()()
23+
% mtimes :: ({FunHandle (a -> b)}, a) -> b
24+
function result = mtimes (this, val)
25+
result = this.d_funHandle (val);
26+
end
27+
28+
% composition
29+
% mpower :: ({FunHandle (b -> c)}, FunHandle (a -> b)) ->
30+
% FunHandle (a -> c)
31+
function result = mpower (this, fun)
32+
result = Data.FunHandle.lambda1 (@(x) this * (fun * x));
33+
end
34+
end
35+
end

+Data/+FunHandle/lam1.m

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function result = lam1 ()
2+
result = Data.FunHandle.lambda1 (@Data.FunHandle.lambda1);
3+
end

+Data/+FunHandle/lam2.m

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function result = lam2 ()
2+
result = Data.FunHandle.lambda1 (@Data.FunHandle.lambda2);
3+
end

+Data/+FunHandle/lam3.m

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function result = lam3 ()
2+
result = Data.FunHandle.lambda1 (@Data.FunHandle.lambda3);
3+
end

+Data/+FunHandle/lambda1.m

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
% lambda1 :: (a -> b) -> FunHandle (a -> b)
2+
function result = lambda1 (fun)
3+
result = Data.FunHandle.FunHandle (fun);
4+
end

+Data/+FunHandle/lambda2.m

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
% lambda2 :: (a -> b -> c) -> FunHandle (a -> FunHandle (b -> c))
2+
function result = lambda2 (fun)
3+
result = Data.FunHandle.FunHandle (@lambda1_);
4+
function res = lambda1_ (a)
5+
funa = fun (a); % partial application here
6+
res = Data.FunHandle.lambda1 (funa);
7+
end
8+
end

+Data/+FunHandle/lambda3.m

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
% lambda3 :: (a -> b -> c -> d) -> FunHandle (a -> FunHandle (b ->
2+
% FunHandle (c -> d)))
3+
function result = lambda3 (fun)
4+
result = Data.FunHandle.FunHandle (@lambda2_);
5+
function res = lambda2_ (a)
6+
funa = fun (a); % partial application here
7+
res = Data.FunHandle.lambda2 (funa);
8+
end
9+
end

+Data/+List/List.m

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
classdef List < handle & Data.Functor & Data.Monad
1+
classdef List < handle & Data.Functor & Control.Monad.Monad
22

33
methods (Abstract)
44
% Functor instance
5-
result = fmap (fun)
6-
m_fmap (fun)
5+
result = fmap_ (fun)
6+
m_fmap_ (fun)
77

88
% foldrs the list using the handle and a default
99
result = foldr (consFunction, default)
@@ -16,6 +16,10 @@
1616
end
1717

1818
methods
19+
function instance = List ()
20+
instance = instance@Data.Functor ();
21+
end
22+
1923
% concatenate a list of lists (COPY)
2024
function result = concat (this)
2125
result = this.foldl (@foldOne, Data.List.ListEmpty ());

+Data/+List/ListCons.m

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
properties (SetAccess = private)
44
d_value
5+
end
6+
7+
properties (GetAccess = private, SetAccess = private)
58
d_rest
69
end
710

@@ -11,14 +14,15 @@
1114
instance.d_rest = rest;
1215
end
1316

14-
function result = fmap (this, fun)
17+
function result = fmap_ (this, fun)
1518
rest = this.d_rest.fmap (fun);
1619
result = Data.List.ListCons (fun (this.d_value), rest);
1720
end
1821

19-
function m_fmap (this, fun)
22+
function result = m_fmap_ (this, fun)
2023
this.d_value = fun (this.d_value);
2124
this.d_rest.m_fmap (fun);
25+
result = this;
2226
end
2327

2428
function result = foldr (this, consFunction, default)

+Data/+List/ListEmpty.m

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
function instance = ListEmpty
55
end
66

7-
function result = fmap (this, fun)
7+
function result = fmap_ (this, fun)
88
result = Data.List.ListEmpty ();
99
end
1010

11-
function m_fmap (this, fun)
11+
function result = m_fmap_ (this, fun)
12+
result = this;
1213
end
1314

1415
function result = foldr (this, consFunction, default)

+Data/+Matrix/Matrix.m

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
classdef Matrix < handle & Data.Functor
2+
3+
properties (SetAccess = private)
4+
d_matrix
5+
end
6+
7+
methods
8+
function instance = Matrix (matrix)
9+
instance.d_matrix = matrix;
10+
end
11+
12+
function result = fmap (this, fun)
13+
result = arrayfun (fun, this.d_matrix);
14+
end
15+
16+
function m_fmap (this, fun)
17+
this.d_matrix = this.fmap (fun);
18+
end
19+
20+
function result = filter (this, fun)
21+
result = this.d_matrix (fun (this.d_matrix));
22+
end
23+
24+
function result = m_filter (this, fun)
25+
this.d_matrix = this.filter (fun);
26+
end
27+
end
28+
end

+Data/+Maybe/Just.m

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
instance.d_value = value;
1010
end
1111

12-
function result = fmap (this, fun)
13-
result = Just (fun (this.d_value));
12+
function result = fmap_ (this, fun)
13+
result = Data.Maybe.Just (fun (this.d_value));
1414
end
1515

16-
function m_fmap (this, fun)
16+
function result = m_fmap_ (this, fun)
1717
this.d_value = fun (this.d_value);
18+
result = this;
1819
end
1920

2021
function result = maybe (this, default, justFunction)

+Data/+Maybe/Maybe.m

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
classdef Maybe < Data.Functor & handle
1+
classdef Maybe < handle & Data.Functor & Control.Monad
22

33
methods (Abstract)
44
% functor instance
5-
result = fmap (fun)
6-
m_fmap (fun)
5+
result = fmap_ (fun)
6+
m_fmap_ (fun)
77

88
result = maybe (default, justFunction)
99
end
10+
11+
methods
12+
function result = bind (this, fun)
13+
result = this.maybe (Data.Maybe.Nothing (), fun);
14+
end
15+
end
16+
17+
methods (Static)
18+
function result = mreturn (value)
19+
result = Data.Maybe.Just (value);
20+
end
21+
end
1022
end

0 commit comments

Comments
 (0)