I've been working on a simple Leetcode problem in Haskell: Max Count of Pos & Neg Integer:
-- First solution
maximumCount :: [Int] -> Int
maximumCount = liftM2 max (length . filter (> 0)) (length . filter (< 0))
-- Custom combinator that's ALMOST the Psi combinator
-- abcde.a(b(ce)(b(de))
myCombinator :: (c -> c -> d) -> (a -> b -> c) -> a -> a -> b -> d
myCombinator f g x y z = f (g x z) (g y z)
-- Second solution
maximumCount' :: [Int] -> Int
maximumCount' = myCombinator max (length .: filter) (> 0) (< 0)
I haven't been able to find an existing combinator that behaves this way. But I am certain that it can be defined by combining existing combinators. I'm still very new to combinatory logic, so I may be unaware of an existing equivalent or perhaps a methodology for deriving a combinator spelling.
I attempted to write a function to combine arguments for a function such that they would be in the correct shape for the on
function, but I was unable to get a proper definition.
It looks like on
operating over a reader (->) a
, so the following ought to work. Note that I started by lifting the binary operator into the reader and invoking on
:
myCombinator op f = on (liftA2 op) f
and then simplified the result:
import Control.Applicative
import Data.Function
myCombinator :: (c -> c -> d) -> (a -> b -> c) -> a -> a -> b -> d
myCombinator = on . liftA2