简体   繁体   中英

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?)

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)

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM