结合仿函数和单子

时间:2014-08-12 09:49:07

标签: haskell monads functor applicative maybe

我是一名哈斯克新手,并且不知道如何以富有表现力的方式结合以下功能:

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

我想要一个这样的函数:

y :: A -> Bool

目前我这样做:

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

嗯,我想,这真的很丑陋(好吧,这里只有字母作为名字,但真正的代码也是丑陋的)。我想要的是功能的连接,更具表现力,如:

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

如何将monadic函数与仿函数结合起来,是否有类似or的东西(如Java 8中的Optional#orElse?)

2 个答案:

答案 0 :(得分:8)

一种方法是使用maybe功能:

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

或者当Zeta指出时,您可以使用无点符号:

y = maybe False h . (g . f)

答案 1 :(得分:5)

要认识到的是,你正在考虑什么都不是假的,但是Haskell并没有假设默认情况下:你需要告诉它。

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

-- or
smash = maybe False id

然后你可以将你的操作与粉碎一起链接

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

编辑:要清楚,这正是你的代码 - 只是美化了一点!