Well, this approach has the problem that the running sum of key <span class="Apple-style-span" style="font-style: italic;">k </span>blocks until a new value for that <span class="Apple-style-span" style="font-style: italic;">k</span> arrives in the input stream.<div>
<br></div><div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif;"><span class="Apple-style-span" style="font-size: small;">If you wanted to know the sum of the values of each key after you got <span class="Apple-style-span" style="font-style: italic;">n</span> elements in the input stream, we could change the </span></span><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif;"><span class="Apple-style-span" style="font-size: small;">valuesWithKey inner function into:</span></span></div>
<div><br></div><div><div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;">runningSumsOfValuesPerKey :: (Eq k, Num v) => [k] -> [(k, v)] -> [[v]]</span></span></div>
<div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;">runningSumsOfValuesPerKey allPossibleKeys = runningSums . allValuesPerKey</span></span></div>
<div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;"> where</span></span></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;"> runningSums = map (scanl (+) 0)</span></span></div>
<div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;"> allValuesPerKey pairs = [ valuesWithKey key pairs | key <- allPossibleKeys ]</span></span></div>
<div><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;"> valuesWithKey key = </span></span><span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-family: 'courier new', monospace;"><span class="Apple-style-span" style="font-size: large;">map (\(k,v) -> if k==key then v else 0)</span></span></span></div>
<div><span class="Apple-style-span" style="font-family: 'courier new'; font-size: 19px; font-weight: bold;"><br></span></div><div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif;"><span class="Apple-style-span" style="font-size: small;">then map (!!n) on the result of </span></span><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif;"><span class="Apple-style-span" style="font-size: small;">runningSumsOfValuesPerKey gives you the sum after n elements arrived.</span></span></div>
<div><br></div><div>I think if you now generalize this so you don't use 0 but mempty, mconcat and other Monoid methods, that you might get something like Luke's trie solution, not sure, Luke is a fair bit smarter than I am :-) </div>
<div><br></div><div>But this code is very inefficient I'm afraid, I guess the blueprint stuff that was posted really builds a map incrementally, but I don't understand that yet.</div><div><br></div><div>Ik spreek Nederlands ja ('t is te zeggen, "Antwerps").</div>
<div><br></div><div>Yes I'm still learning Haskell, but I think with Haskell this is a never ending process, since there's soo much stuff to discover and the language evolves (which makes it both exciting and frustrating, but that's the dilemma of knowledge anyway, the more you know the better you realize the vast amount of knowledge that you don't know yet :-)</div>
<div><br></div><div class="gmail_quote">On Fri, Mar 27, 2009 at 12:53 AM, Guenther Schmidt <span dir="ltr"><<a href="mailto:gue.schmidt@web.de">gue.schmidt@web.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Dear Peter,<br>
<br>
wow, thanks, this is a very ... interesting ... approach, I hadn't thought about that yet ;)<br>
<br>
Ben je nederlands?<br>
<br>
In case you'd be interested to share the "road to Haskell" experience with another newbie just ask.<br>
<br>
Günther<br>
<br>
Peter Verswyvelen schrieb:<div><div></div><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'm also learning Haskell so the solution below might be (1) inefficient and (2) incorrect, but hey, let's give it a try :-)<br>
<br>
For simplicity, in the testing code, I assume an infinite list of key/value pairs where they keys are of type Char between 'a' and 'z' and the values are Integers (the code also seems to work for keys with just a lower bound but no upper bound)<br>
I think the code speaks for itself<br>
<br>
import System.Random<br>
runningSumsOfValuesPerKey :: (Eq k, Num v) => [k] -> [(k, v)] -> [[v]]<br>
runningSumsOfValuesPerKey allPossibleKeys = runningSums . allValuesPerKey<br>
where<br>
runningSums = map (scanl (+) 0)<br>
allValuesPerKey pairs = [ valuesWithKey key pairs | key <- allPossibleKeys ]<br>
valuesWithKey key = map snd . filter ((==key) . fst)<br>
-- Testing<br>
randomPairs :: [(Char, Integer)]<br>
randomPairs = zip keys values<br>
where<br>
keys = randomRs ('a','z') rnd1<br>
values = randomRs (0,9) rnd2<br>
(rnd1,rnd2) = split (mkStdGen 0)<br>
test = map (take 10) [rs `atKey` 'c', rs `atKey` 'z']<br>
where<br>
rs = runningSumsOfValuesPerKey ['a'..] randomPairs<br>
xs `atKey` k = xs !! (fromEnum k - fromEnum 'a')<br>
<br>
<br>
<br>
</blockquote>
<br>
<br>
</div></div></blockquote></div><br></div></div>