@@ -2,9 +2,7 @@ package bescala
2
2
3
3
import java .util .concurrent .ExecutorService
4
4
5
- import language .{higherKinds , implicitConversions }
6
-
7
- import Util .async
5
+ import scala .language .{higherKinds , implicitConversions }
8
6
9
7
trait Common {
10
8
@@ -24,97 +22,112 @@ trait Common {
24
22
// abstract M[A] related
25
23
//
26
24
27
- def fromM [A ](ma : M [A ]): A
25
+ def fromM [A ](ma : M [A ]): A
28
26
29
- def toM [A ](a : => A ): M [A ]
27
+ def toM [A ](a : => A ): M [A ]
30
28
31
29
//
32
- // abstract applicative and monad Par[A] features
30
+ // abstract applicative and monadic Par[A] computational features
33
31
//
34
32
35
- def map [A , B ](parA : Par [A ])(a2b : A => B ): Par [B ]
33
+ def map [A , B ](pa : Par [A ])(a2b : A => B ): Par [B ]
36
34
37
- def map2 [A , B , C ](parA : Par [A ], parB : Par [B ])(ab2c : (A , B ) => C ): Par [C ]
35
+ def map2 [A , B , C ](pa : Par [A ], pb : Par [B ])(ab2c : (A , B ) => C ): Par [C ]
38
36
39
- def flatMap [A , B ](parA : Par [A ])(a2pb : A => Par [B ]): Par [B ]
37
+ def flatMap [A , B ](pa : Par [A ])(a2pb : A => Par [B ]): Par [B ]
40
38
41
39
//
42
- // only extra abstract Par[A] feature
40
+ // only extra abstract Par[A] computational feature
43
41
//
44
42
45
- def fork [A ](parA : => Par [A ]): Par [A ]
43
+ def fork [A ](pa : => Par [A ]): Par [A ]
46
44
47
45
//
48
46
// concrete
49
47
//
50
48
49
+ // monadic unit in terms of toM
51
50
def unit [A ](a : => A ): Par [A ] =
52
- es =>
53
- toM(a)
51
+ es =>
52
+ toM(a)
53
+
54
+ // monadic run in terms of fromM
55
+ def run [A ](es : ExecutorService )(pa : => Par [A ]): A =
56
+ fromM(pa(es))
54
57
55
- def run [A ](es : ExecutorService )(parA : => Par [A ]): A =
56
- fromM(parA(es))
58
+ //
59
+ // more concrete stuff
60
+ //
57
61
58
- def join [A ](parParA : Par [Par [A ]]): Par [A ] =
59
- flatMap(parParA )(identity)
62
+ def join [A ](ppa : Par [Par [A ]]): Par [A ] =
63
+ flatMap(ppa )(identity)
60
64
61
- def choice [A ](parBoolean : Par [Boolean ])(trueParA : Par [A ], falseParA : Par [A ]): Par [A ] =
62
- flatMap(parBoolean )(b => if (b) trueParA else falseParA )
65
+ def choice [A ](pb : Par [Boolean ])(tpa : Par [A ], fpa : Par [A ]): Par [A ] =
66
+ flatMap(pb )(b => if (b) tpa else fpa )
63
67
64
- def choiceN [A ](parInt : Par [Int ])(parAs : List [Par [A ]]): Par [A ] =
65
- flatMap(parInt)(parAs (_))
68
+ def choiceN [A ](pi : Par [Int ])(pas : List [Par [A ]]): Par [A ] =
69
+ flatMap(pi)(pas (_))
66
70
67
- def choiceMap [K ,V ](parK : Par [K ])(choices : Map [K , Par [V ]]): Par [V ] =
68
- flatMap(parK )(choices)
71
+ def choiceMap [K , V ](pk : Par [K ])(choices : Map [K , Par [V ]]): Par [V ] =
72
+ flatMap(pk )(choices)
69
73
70
- def sequence [A ](parAs : List [Par [A ]]): Par [List [A ]] =
71
- parAs.foldRight[Par [List [A ]]](unit(List ()))(map2(_, _)(_ :: _))
74
+ // quadratic instead of linear `pas.foldRight[Par[List[A]]](unit(List()))(map2(_, _)(_ :: _))`
75
+ def sequence [A ](pas : List [Par [A ]]): Par [List [A ]] = {
76
+ if (pas.isEmpty) unit(List ())
77
+ else if (pas.length == 1 ) map(pas.head)(List (_))
78
+ else {
79
+ val (lpas, rpas) = pas.splitAt(pas.length / 2 )
80
+ val plas = sequence(lpas)
81
+ val pras = sequence(rpas)
82
+ map2(plas, pras)(_ ++ _)
83
+ }
84
+ }
72
85
73
86
def mapList [A , B ](as : List [A ])(a2b : A => B ): Par [List [B ]] =
74
87
sequence(as.map(forkedFunction(a2b)))
75
88
76
- def filterList [A ](as : List [A ])(predicateA : A => Boolean ): Par [List [A ]] =
77
- map(sequence(as map (a => unit(if (predicateA (a)) List (a) else List ()))))(_.flatten)
89
+ def filterList [A ](as : List [A ])(a2b : A => Boolean ): Par [List [A ]] =
90
+ map(sequence(as map (a => unit(if (a2b (a)) List (a) else List ()))))(_.flatten)
78
91
79
92
//
80
- // forked versions
93
+ // some forked versions
81
94
//
82
95
83
96
def forkedUnit [A ](a : => A ): Par [A ] =
84
97
fork(unit(a))
85
98
86
- def forkedMap [A , B ](parA : Par [A ])(a2b : A => B ): Par [B ] =
87
- map(fork(parA))(a2b)
88
- // fork(map(fork(parA))(a2b))
99
+ def forkedMap [A , B ](pa : Par [A ])(a2b : A => B ): Par [B ] =
100
+ map(fork(pa))(a2b)
89
101
90
- def forkedMap2 [A ,B ,C ](parA : Par [A ], parB : Par [B ])(ab2c : (A ,B ) => C ): Par [C ] =
91
- map2(fork(parA), fork(parB))(ab2c)
92
- // fork(map2(fork(parA), fork(parB))(ab2c))
102
+ def forkedMap2 [A , B , C ](pa : Par [A ], pb : Par [B ])(ab2c : (A , B ) => C ): Par [C ] =
103
+ map2(fork(pa), fork(pb))(ab2c)
93
104
94
- def forkedSequence [A ](parAs : List [Par [A ]]): Par [List [A ]] = fork {
95
- if (parAs.isEmpty) unit(List ())
96
- else if (parAs.length == 1 ) forkedMap(parAs.head)(List (_))
105
+ // also quadratic
106
+ def forkedSequence [A ](pas : List [Par [A ]]): Par [List [A ]] = {
107
+ if (pas.isEmpty) unit(List ())
108
+ else if (pas.length == 1 ) forkedMap(pas.head)(List (_))
97
109
else {
98
- val (leftParAs, rightParAs ) = parAs .splitAt(parAs .length/ 2 )
99
- forkedMap2(forkedSequence(leftParAs ), forkedSequence(rightParAs ))(_ ++ _)
110
+ val (lpas, rpas ) = pas .splitAt(pas .length / 2 )
111
+ forkedMap2(forkedSequence(lpas ), forkedSequence(rpas ))(_ ++ _)
100
112
}
101
113
}
102
114
103
115
def forkedFunction [A , B ](a2b : A => B ): A => Par [B ] =
104
- a => forkedUnit(a2b(a))
116
+ a =>
117
+ forkedUnit(a2b(a))
105
118
106
119
def forkedMapList [A , B ](as : List [A ])(a2b : A => B ): Par [List [B ]] =
107
120
forkedSequence(as.map(forkedFunction(a2b)))
108
121
109
- def forkedFilterList [A ](as : List [A ])(predicateA : A => Boolean ): Par [List [A ]] =
110
- forkedMap(forkedSequence(as map (a => forkedUnit(if (predicateA (a)) List (a) else List ()))))(_.flatten)
122
+ def forkedFilterList [A ](as : List [A ])(a2b : A => Boolean ): Par [List [A ]] =
123
+ forkedMap(forkedSequence(as map (a => forkedUnit(if (a2b (a)) List (a) else List ()))))(_.flatten)
111
124
112
125
//
113
126
// example: sorting
114
127
//
115
128
116
- def sort [A : Ordering ](parAs : Par [List [A ]]) = map(parAs )(_.sorted)
129
+ def sort [A : Ordering ](pas : Par [List [A ]]) = map(pas )(_.sorted)
117
130
118
- def forkedSort [A : Ordering ](parAs : Par [List [A ]]) = forkedMap(parAs )(_.sorted)
131
+ def forkedSort [A : Ordering ](pas : Par [List [A ]]) = forkedMap(pas )(_.sorted)
119
132
120
133
}
0 commit comments