如何很好地表示三个条件的替代方案?

gaa*_*kam 0 haskell

假设我有一个角色c :: Char。现在,我想看看它是否等于aisDigit

isAOrDigit = (||) <$> (=='a') <*> (isDigit)
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。但现在我想看看它是否等于aisDigit或介于dg。不幸的是,由于||仅接受2个参数,所以我不能说(||) <$> (=='a') <*> (isDigit) <*> (`elem`['d'..'g'])

有没有什么好办法可以写这个,还是我必须回到这个:

isACOrDigitOrDG c = c == 'a' || isDigit c || c `elem` ['d'..'g']
Run Code Online (Sandbox Code Playgroud)

4ca*_*tle 8

您可以使用sequence将转换[a -> Bool]a -> [Bool]。然后,您可以使用or合并该[Bool]值。

isACOrDigitOrDG = or . sequence
    [ (== 'a')
    , isDigit
    , (`elem` ['d'..'g'])
    ]
Run Code Online (Sandbox Code Playgroud)


Rei*_*chs 8

您可以解除(||)操作员:

(<||>) = liftA2 (||)

> :t (== 'a') <||> isDigit <||> (`elem` ['d'..'g'])
(== 'a') <||> isDigit <||> (`elem` ['d'..'g']) :: Char -> Bool

> (== 'a') <||> isDigit <||> (`elem` ['d'..'g']) $ 'a'
True
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您希望此(或您的)短路,则必须加倍努力:http://hackage.haskell.org/package/cond-0.4.1.1/docs/Control-Conditional.html#v :-60--124--124--62- (4认同)
  • @ReinHenrichs不需要额外的照顾。您链接到的包要格外小心,因为它试图对任意monad进行概括。但是特别是monads的读者家族在其“副作用”方面已经足够懒惰了。您会发现自己是这样的:`liftA2(||)(const True)undefined undefined`根据需要返回`True`,而无需额外的工作。 (3认同)