@@ -28,9 +28,9 @@ import Control.Concurrent (threadDelay)
2828--------------------------------------------------------------------------------
2929
3030-- | MapReduce skeleton
31−data MapReduce k1 v1 k2 v2 = MapReduce {
31+data MapReduce k1 v1 k2 v2 v3 = MapReduce {
3232 mrMap :: k1 -> v1 -> [(k2, v2)]
33− , mrReduce :: k2 -> [v2] -> v2
33+ , mrReduce :: k2 -> [v2] -> v3
3434 } deriving (Typeable)
3535
3636-- | Local (non-distributed) implementation of the map-reduce algorithm
@@ -38,19 +38,19 @@ data MapReduce k1 v1 k2 v2 = MapReduce {
3838-- This can be regarded as the specification of map-reduce; see
3939-- /Google’s MapReduce Programming Model---Revisited/ by Ralf Laemmel
4040-- (<http://userpages.uni-koblenz.de/~laemmel/MapReduce/>).
41−localMapReduce :: forall k1 k2 v1 v2. Ord k2 =>
42− MapReduce k1 v1 k2 v2
41+localMapReduce :: forall k1 k2 v1 v2 v3. Ord k2 =>
42+ MapReduce k1 v1 k2 v2 v3
4343 -> Map k1 v1
44− -> Map k2 v2
44+ -> Map k2 v3
4545localMapReduce mr = reducePerKey mr . groupByKey . mapPerKey mr
4646
47−reducePerKey :: MapReduce k1 v1 k2 v2 -> Map k2 [v2] -> Map k2 v2
47+reducePerKey :: MapReduce k1 v1 k2 v2 v3 -> Map k2 [v2] -> Map k2 v3
4848reducePerKey mr = Map.mapWithKey (mrReduce mr)
4949
5050groupByKey :: Ord k2 => [(k2, v2)] -> Map k2 [v2]
5151groupByKey = Map.fromListWith (++) . map (second return)
5252
53−mapPerKey :: MapReduce k1 v1 k2 v2 -> Map k1 v1 -> [(k2, v2)]
53+mapPerKey :: MapReduce k1 v1 k2 v2 v3 -> Map k1 v1 -> [(k2, v2)]
5454mapPerKey mr = concatMap (uncurry (mrMap mr)) . Map.toList
5555
5656--------------------------------------------------------------------------------
@@ -63,11 +63,11 @@ matchDict SerializableDict = match
6363sendDict :: forall a. SerializableDict a -> ProcessId -> a -> Process ()
6464sendDict SerializableDict = send
6565
66−mapperProcess :: forall k1 v1 k2 v2.
66+mapperProcess :: forall k1 v1 k2 v2 v3.
6767 SerializableDict (ProcessId, k1, v1)
6868 -> SerializableDict [(k2, v2)]
6969 -> ProcessId
70− -> MapReduce k1 v1 k2 v2
70+ -> MapReduce k1 v1 k2 v2 v3
7171 -> Process ()
7272mapperProcess dictIn dictOut workQueue mr = do
7373 us <- getSelfPid
@@ -97,30 +97,30 @@ mapperProcess dictIn dictOut workQueue mr = do
9797
9898remotable ['mapperProcess]
9999
100−mapperProcessClosure :: forall k1 v1 k2 v2.
101− (Typeable k1, Typeable v1, Typeable k2, Typeable v2)
100+mapperProcessClosure :: forall k1 v1 k2 v2 v3.
101+ (Typeable k1, Typeable v1, Typeable k2, Typeable v2, Typeable v3)
102102 => Static (SerializableDict (ProcessId, k1, v1))
103103 -> Static (SerializableDict [(k2, v2)])
104− -> Closure (MapReduce k1 v1 k2 v2)
104+ -> Closure (MapReduce k1 v1 k2 v2 v3)
105105 -> ProcessId
106106 -> Closure (Process ())
107107mapperProcessClosure dictIn dictOut mr pid =
108108 closure decoder (encode pid) `closureApply` mr
109109 where
110− decoder :: Static (ByteString -> MapReduce k1 v1 k2 v2 -> Process ())
110+ decoder :: Static (ByteString -> MapReduce k1 v1 k2 v2 v3 -> Process ())
111111 decoder =
112112 ($(mkStatic 'mapperProcess) `staticApply` dictIn `staticApply` dictOut)
113113 `staticCompose`
114114 staticDecode sdictProcessId
115115
116−distrMapReduce :: forall k1 k2 v1 v2.
117− (Serializable k1, Serializable v1, Serializable k2, Serializable v2, Ord k2)
116+distrMapReduce :: forall k1 k2 v1 v2 v3.
117+ (Serializable k1, Serializable v1, Serializable k2, Serializable v2, Serializable v3, Ord k2)
118118 => Static (SerializableDict (ProcessId, k1, v1))
119119 -> Static (SerializableDict [(k2, v2)])
120− -> Closure (MapReduce k1 v1 k2 v2)
120+ -> Closure (MapReduce k1 v1 k2 v2 v3)
121121 -> [NodeId]
122122 -> Map k1 v1
123− -> Process (Map k2 v2)
123+ -> Process (Map k2 v3)
124124distrMapReduce dictIn dictOut mr mappers input = do
125125 us <- getSelfPid
126126 slavesTerminated <- liftIO $ newEmptyMVar