Applying multiple functions to the same value point-free style in Haskell

后端 未结 4 645
醉酒成梦
醉酒成梦 2021-02-01 16:14

I was bored one day and wanted to exercise my brain, so I decided to do the 99 Haskell Problems but restricted myself to doing them in point-free style. A problem that seems to

4条回答
  •  滥情空心
    2021-02-01 16:56

    There are a few basic idiomatic combinators which pop up repeatedly, and are reimplemented with various higher concepts and libraries, but which are essentially very simple. Names may vary, and some are implementable in terms of others:

    fork (f,g) x = (f x, g x)              -- == (f &&& g)
    prod (f,g) x = (f $ fst x, g $ snd x)  -- == (f *** g)
    pmap f (x,y) = (f x, f y)              -- == (f *** f)
    dup     x    = (x,x)
    

    etc. Of course uncurry f (x,y) == f x y gets used a lot with these, too.

    &&& and *** are defined in Control.Arrow, as well as first and second. Then prod (f,id) == first f, prod(id,g) == second g etc. etc.

    So your foobar becomes

    foobar = (\(a,b)->[a,b]) . fork (id,reverse)
           = (\(a,b)->[a,b]) . (id &&& reverse)
           = (\(a,b)->[a,b]) . (id *** reverse) . dup 
           = join $ curry ( (\(a,b)->[a,b]) . second reverse)
    

    For the last one you need to also import Control.Monad and Control.Monad.Instances. See also this question.


    late edit: also, using Control.Applicative as hinted in answer by ertes,

           = (:) <*> ((:[]) . reverse)
    

提交回复
热议问题