Boris Buliga


(tagged 'semigroup)

Predicate composition

January 20, 2020

They say functional programming has many essences and the composition is one of them. Thanks to the wonderful dot operator, we know how to compose functions like a -> b and b -> c to get a function a -> c. But in some cases functions are not that simple and it becomes tricky to compose them nicely.

valid :: a -> Bool
valid = \a -> check1 a && (check2 a || check3 a)
  where check1 = undefined :: a -> Bool
        check2 = undefined :: a -> Bool
        check3 = undefined :: a -> Bool

It would be lovely to express it in a more declarative way by abstracting away function application and result combination.

valid :: a -> Bool
valid = check1 .&& (check2 .|| check3)

(.&&) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
(.||) :: (a -> Bool) -> (a -> Bool) -> a -> Bool

Apart from implementing combinators for predicate composition, we want to avoid any runtime penalty from using abstractions. In this article we are going to implement the following functions and investigate how far we can go with abstractions until performance degrades. Or maybe it won’t degrade. Who knows?

Read more →