List types

Tom Pledger Tom.Pledger@peace.com
Mon, 13 Nov 2000 18:15:39 +1300


Eric Allen Wohlstadter writes:
 > I would like to be able to make a list that contains functions which take
 > arguments of a certain type 'a'. However I don't know how many 'a'
 > arguments there are. For example I'd like to be able to make a list of
 > f,g, and h.
 > 
 > f::a->b
 > g::a->a->b
 > h::a->a->a->b
 > [f,g,h]
 > 
 > Now I could make a function l that takes a list of 'a'.
 > l::[a]->b
 > However, I want to be able to curry the a's one at a time.
 > 
 > My solution so far is declare a type Element like this:
 > data Element a b c d = One a | Two b | Three c | Four d
 > and then I can make my list like this,
 > [One f,Two g,Three h]
 > 
 > This gets very ugly. Do you guys have any ideas?
 > 
 > 	Eric Wohlstadter
 > 	UCDavis Software Engineering

Hi.

It looks a lot like a folding task.  It would be nice if you could
formulate it the l::[a]->b way, and feed in the arguments in a lazy
list.

Failing that, how about a product of lists, instead of a list of sums?

    data Bunch a b =
        Bunch {nones  :: [b],
               ones   :: [a->b],
               twos   :: [a->a->b],
               threes :: [a->a->a->b],
               fours  :: [a->a->a->a->b]}

    emptyBunch = Bunch [] [] [] [] []

    applyBunch b arg =
        Bunch (map ($arg) (ones   b))
              (map ($arg) (twos   b))
              (map ($arg) (threes b))
              (map ($arg) (fours  b))
              []

    f x1       = ()
    g x1 x2    = ()
    h x1 x2 x3 = ()

    fgh = emptyBunch {ones=[f], twos=[g], threes=[h]}

    test = take 5 (map nones (iterate (\b -> applyBunch b "foo") fgh))

Regards,
Tom