Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining functors and monads

I'm a haskell newbie and don't know, how to combine following functions in an expressive way:

f :: A -> B
g :: B -> Maybe C
h :: C -> Bool

I want a function like this:

y :: A -> Bool

Currently I'm doing it like that:

y a = case (fmap h ((g.f) a)) of {
            Just b -> b;
            Nothing -> False}

Well, I think, this is really ugly (Ok, here are only letters as names, but the real code is ugly, too). What I want is a concatenation of the functions, which is more expressive, like:

y a = (h.g.f) a `or` False

How is it possible to combine monadic functions with functors and is there something like or (like Optional#orElse in Java 8?)

like image 352
F. Böller Avatar asked Dec 12 '22 04:12

F. Böller


2 Answers

One way would be to use the maybe function:

y :: A -> Bool
y a =  maybe False h (g $ f a)

Or as Zeta points out, you can use the pointfree notation:

y = maybe False h . (g . f)
like image 68
Sibi Avatar answered Jan 03 '23 02:01

Sibi


The thing to recognize is that you're considering Nothing to be falsey, but Haskell doesn't assume that by default: you need to tell it.

smash :: Maybe Bool -> Bool
smash Nothing = False
smash (Just v) = v

-- or
smash = maybe False id

Then you can chain your operations along with the smashing

it :: A -> Bool
it = smash . fmap h . g . f

Edit: to be clear, this is exactly your code—just prettified a bit!

like image 24
J. Abrahamson Avatar answered Jan 03 '23 02:01

J. Abrahamson