I had a similar example today in the functional programming slack.
> hello, quick question: i feel like there's a more elegant way to express this, but I'm struggling to come up with one:
foo :: (a -> Bool) -> (a -> Bool) -> a -> Bool
foo f g x = f x && g x
For those who aren't as familiar with Haskell, that is taking a function f and a function g, passing argument x to both, and then doing a binary and on their boolean result.One answer suggested:
> You can get fancy, but the “simple” version is almost always more readable:
(not . null . f $ x) && (not . null . g $ x)
Which I find myself agreeing with in many ways, but for some reason leaves me desiring more.The answer to that desire complements this article I think:
> if f and g returned Maybe you could have:
> f _ = Nothing
> g _ = Just ()
> x = ()
> (f x) <*> (g x)
Nothing
> import Data.Maybe
> (f x) <*> (g x) & isJust
False
> -- or to avoid <*> you can do
> liftA f g x
Nothing
If that's not clear, let me know what's confusing and I'll try to explain further