Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Going through SICP in Haskell

Name: Anonymous 2010-03-26 11:27

I've been going through SICP, first in Scheme and then in Haskell, and I started wondering...

Is my Haskell too Lisp-y?

filterAccumulate
    :: (Eq t1) =>
       (t1 -> Bool) -> (t2 -> t3 -> t3) -> t3 -> (t1 -> t2) -> t1 -> (t1 -> t1) -> t1 -> t3
filterAccumulate filter combiner nullVal term a next b =
    iter a nullVal
    where
    iter a result =
        if (a == b) then filterCombiner a result
        else iter (next a) (filterCombiner a result)
    filterCombiner a result =
        if (filter a) then combiner (term a) result
        else result

Name: Anonymous 2011-01-23 12:40

YHBT

Name: Anonymous 2011-01-23 12:41

YHBT

Name: Anonymous 2011-01-23 12:42

YHBT

Name: Anonymous 2011-01-23 12:42

YHBT

Name: Anonymous 2011-01-23 12:43

YHBT

Name: Anonymous 2011-01-23 12:44

YHBT

Name: Anonymous 2011-01-23 12:45

YHBT

Name: Anonymous 2011-01-23 12:46

YHBT

Name: Anonymous 2011-01-23 12:47

YHBT

Name: Anonymous 2011-01-23 12:48

YHBT

Name: Anonymous 2011-01-23 12:49

YHBT

Name: Anonymous 2011-01-23 12:50

YHBT

Name: Anonymous 2011-01-23 12:51

YHBT

Name: Anonymous 2011-01-23 12:52

YHBT

Name: Anonymous 2011-01-23 12:53

YHBT

Name: Anonymous 2011-01-23 12:54

YHBT

Name: Anonymous 2011-01-23 12:54

YHBT

Name: Anonymous 2011-01-23 12:55

YHBT

Name: Anonymous 2011-01-23 12:56

YHBT

Name: Anonymous 2011-01-23 12:57

YHBT

Name: Anonymous 2011-01-23 12:58

YHBT

Name: Anonymous 2011-01-23 12:59

YHBT

Name: Anonymous 2011-01-23 13:00

YHBT

Name: Anonymous 2011-01-23 13:01

YHBT

Name: Anonymous 2011-01-23 13:02

YHBT

Name: Anonymous 2011-01-23 13:03

YHBT

Name: Anonymous 2011-01-23 13:04

YHBT

Name: Anonymous 2011-01-23 13:05

YHBT

Name: Anonymous 2011-01-23 13:06

YHBT

Name: Anonymous 2011-01-23 13:06

YHBT

Name: Anonymous 2011-01-23 19:16

>>18
Syntactic sugar is sweet. If you find that it's too sweet for your taste, you may as well return to Scheme.

Name: Anonymous 2011-01-24 10:16

>>1
derp

Name: Anonymous 2013-09-15 17:15

>>1

Looking at your code I made first a little rewrite to make your type more recognizable, then I recognized, what it actually did.

So what you are actually doing is the following pipeline:

fold . filter . unfold

This code can be much neater written like this:


import Data.List
import Test.QuickCheck
import Text.Show.Fu
unfoldy :: (t1 -> Maybe t1) -> t1 -> [t1]
unfoldy f  s = s : unfoldr (fmap (\x -> (x,x)) . f) s  

filterAccumulate' :: (s -> Bool) -> (b -> s -> b) -> b -> (s -> Maybe s) -> s -> b
filterAccumulate' pred f z g  = foldl' f z . filter pred . unfoldy g


I recognize you are actually fusing together two functions. So you can change the pipeline to :

unfoldr . foldr


filterAccumulate'' :: (b -> s -> b) -> b -> (s -> Maybe s) -> s -> b
filterAccumulate'' f z g = foldl' f z . unfoldy g



For test if the function behave the same:


prop_same = property (forAll (suchThat arbitrary (uncurry (<))) $ \(b,e) ->
                        forAll (elements [even, odd, (>10), (<10)]) $ \f -> sameThree $ test_same f b e)
                       

sameThree :: Eq a => (a,a,a) -> Bool
sameThree (a,b,c) = a == b && b == c

test_same :: (Int -> Bool) -> Int -> Int -> ([String], [String], [String])
test_same f b e = (filterAccumulate f b succ e show (:) [], filterAccumulate' f step [] next b, filterAccumulate'' step' [] next b)
        where step z x = show x : z
              next x | x < e = Just (succ x)
                     | otherwise = Nothing
              step' z x | f x = show x : z
                        | otherwise = z



As kicker you can also write it as an hylomorphism, but I am starting to lose my interest. But to cut some trees for you in the forest, so you can see the actual forest (haha), I give you this:



hylo e g = e . fmap (hylo e g) . g

filterAccumulateHylo = hylo step next 
    where step (a,b) | even a = show a : b
                     | otherwise = b
          next a = (succ a, succ a)


Which generates an infinite list:


take 10 $ filterAccumulateHylo


If you can write it as an hylomorphism, your code will be short and efficient.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List