4

我是一个haskell新手,不知道如何以富有表现力的方式组合以下功能:

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

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

4

2 回答 2

8

一种方法是使用Maybe功能:

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

或者正如Zeta指出的那样,您可以使用 pointfree 表示法:

y = maybe False h . (g . f)
于 2014-08-12T09:56:48.893 回答
5

要认识到的是,您认为 Nothing 是虚假的,但 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

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

于 2014-08-12T15:28:42.893 回答