Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Help refactor monster function (Gesh hseG) ---------------------------------------------------------------------- Message: 1 Date: Thu, 21 Apr 2016 09:29:58 +0300 From: Gesh hseG <g...@gesh.uni.cx> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Help refactor monster function Message-ID: <cacs5xqnsqscxksodzdzmbyqzsv8eqciq-khfi3yswbgyg-w...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" On Tue, Apr 19, 2016 at 11:14 AM, D?niel Arat? <exitcons...@gmail.com> wrote: > Hi guys, > > Here is my solution to Problem 50 from Ninety-Nine Haskell Problems: > https://github.com/nilthehuman/H-99/blob/master/Logic.hs#L75 > > (`consume' is defined here: > https://github.com/nilthehuman/H-99/blob/master/Lists.hs#L107 ) > > I'm not satisfied with the code quality. I feel like especially `go', > `group' and `min2' should be more succint and readable. > D?niel, Looking at your code, there are several things that I note immediately. First, your 'consume' combinator can be rewritten as > consume f g a = foldl f a . chunk g > chunk g = unfoldr (fmap g . (\xs -> if null xs then Nothing else Just xs)) Second, you may want to reconsider your data model. As it is, your code is inefficient, since you are simulating priority queues using lists. Not everything can be solved naturally with lists. Assume we proceed anyway with your model, despite these misgivings. Note that any operation on your symbols is most naturally expressed in terms of sets of symbols with a common root. Hence, you may want to use > gatherRoots = chunk (partition (compare `on` root)) to split your queue into these sets. Note that this also gives you an easier way of expressing 'done' as > done = (<=1) . length . gatherRoots Once that is obtained, you want the minimal two sets by weight. Hence: > (x:y:xs) = map fst . sortBy (compare `on` snd) . map (id &&& flatten) > where flatten = sum . map weight > weight (_,w,_,_) = w Finally, you want to > go xs = map (update '0') x ++ map (update '1') y ++ xs > where update p (c,w,ps,_) = (c,w,p:ps, rn) > rn = rNext xs Note that this also avoids the ugly nested-if you had there. I played around with your code and refactored it to my taste. I extracted the main priority-queue simulation code into a typeclass instance so that you can see that the majority of the complexity of your code comes from simulating priority queues using lists. The completed code is here [0]. Note that I've taken some liberties with the naming and refactoring, and this may not all be to your taste. YMMV. I hope this helps, and that the criticism I gave was correct and will be well-received. Regards, Gesh P.S. You would be correct in claiming that this rewrite is too distant from the original to be of use. My apologies if this is the case. [0] - https://gist.github.com/anonymous/cd4e21105676894dcd579fcf8d4c4b41 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160421/70002b84/attachment-0001.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 94, Issue 18 *****************************************