I am just working through some simple exercises in haskell and was wondering if there was a point-free way of converting an if-then-else statement into a Maybe
type: Nothing
being returned if the condition is false, and Just
the input if the condition is true.
In short, given some:
maybeIf :: (a -> Bool) -> a -> Maybe a
maybeIf cond a = if cond a then Just a else Nothing
Is there an implementation that is point-free with respect to a
? I've also been looking at a more concrete version, a -> Maybe a
, and feel like there may be an answer somewhere in Control.Arrow
. However, since Maybe
is a data type and if-else statements control data flow, I'm unsure if there is a clean way of doing it.
If we choose a Church-encoding for Booleans…
Then we can write a point-free
maybeIf
in Applicative-style.Some intuitions…
Here is a rendering in PNG format of the above "intuitions", in case your installed fonts do not support the needed unicode characters.
So therefore:
This function is defined in Control.Monad.Plus and is called partial
You can import
find
fromData.Foldable
and then it's quite simply:The function
find
is not complicated so you could quite easily define it yourself less generically, in terms ofMaybe
, but it isn't actually so different from your own implementation ofmaybeIf
so you might not gain much, depending on why you wanted to do it.Following dfeuer's lead (and using Daniel Wagner's new name for this function),
join
is a monadic function,join :: Monad m => m (m a) -> m a
, but for functions it is simplyjoin
is accepted as a replacement for W combinator in point-free code.You only wanted it point-free with respect to the value argument, but it's easy to transform the equation with
join
further (readability of the result is another issue altogether), asIndeed,
But I'd much rather see
\p x -> listToMaybe [x | p x]
in an actual code.Or just
\p x -> [x | p x]
, with Monad Comprehensions. Which is the same as Daniel Wagner'sx <$ guard (p x)
, only with different syntax.The main thing getting in the way of making that pointfree is the
if
/then
/else
. You can define anif'
combinator, or you can use this generalized version that I define and use often:Standard tools give successive point-free versions as
though I really don't think either are better than the pointful version.