2

I want to create a pointfree function that takes a list of functions, applies a single argument to each listed function, and then compresses the list via another function. A pointfree version of this function would have the following type signature:

multiplex :: ([a] -> b) -> [(c -> a)] -> (c -> b)

And an example usage:

invariantsHold :: (Integral a) => a -> Bool
invariantsHold = multiplex (all id) [(>=0),(<=50),even]

I was able to write the following:

multiplex :: ([a] -> b) -> [(c -> a)] -> c -> b
multiplex f xs e = f $ map ((flip ($)) e) xs

This implementation is not pointfree, how can I transform this function to a pointfree representation?

recursion.ninja
  • 5,377
  • 7
  • 46
  • 78
  • [Lambdabot](http://www.haskell.org/haskellwiki/Lambdabot) suggests this beauty: `(. flip (map . flip id)) . (.)` – duplode Apr 19 '14 at 18:04
  • @duplode I was looking for a documented function transformation like [this](http://stackoverflow.com/a/8465619/1465011) or [this](http://stackoverflow.com/a/13426526/1465011). The goal is to try and make the function more readable while reducing the points in the definition. Lambdabot's "beauty" *while correct*, doesn't given me information necessary *to improve* the function. – recursion.ninja Apr 19 '14 at 18:15
  • 1
    I know; that is why I did not post it as an answer. In any case, `($ e)` instead of `((flip ($)) e)` would improve readability quite a bit. – duplode Apr 19 '14 at 18:23
  • If you swapped the `[c -> a]` and `c` then it's just `(.: map . flip ($))` where `(.:) = (.) . (.)` – daniel gratzer Apr 19 '14 at 18:28
  • @jozefg There's always: `((.: map . flip ($)) ^>) where (.:) = (.).(.); (^>) = flip . flip .(.) flip` – recursion.ninja Apr 19 '14 at 20:09
  • Your last one can be improved if you know that `map . flip ($)` is `flip sequence` for the `(->) a` Monad. After which you may want to switch `[c -> a]` and `c` back. – Ørjan Johansen Apr 20 '14 at 02:34

1 Answers1

3

Not in pointfree style, but surely could be simplified significantly by using Applicative (need to import Control.Applicative):

multiplex f xs e = f $ xs <*> pure e

invariantsHold also could be simplified a little:

invariantsHold = multiplex and [(>=0),(<=50),even]

Using sequenceA (from Data.Traversable) is another way to define this multiplex:

multiplex f xs e = f $ sequenceA xs e

And this definition can be rewritten in pointfree style (give by pointfree):

multiplex = (. sequenceA) . (.)

or

multiplex = flip ((.) . (.)) sequenceA

Beautiful, but seems pointless to me :-)

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47