How to do parallel "either-side" short-circuiting with "and" and "or"
Asked Answered
D

2

11

Does haskell have a parallel "and" method

parAnd :: Bool -> Bool -> Bool

such that

(a `parAnd` b)

will spark the evaluation of a and b in parallel and return false as soon as either a or b evaluates to false (and not wait for the other one)?

Is there some way to implement such a thing?

Deodand answered 14/6, 2014 at 19:54 Comment(0)
K
12

Normally, this is not possible. You can do something like

a `par` b `pseq` (a && b)

but if b evaluates to False, a is still fully evaluated.

However, this is possible with the unambiguous choice operator created by Conal Elliott for his Functional Reactive Programming (FRP) implementation. It's available on Hackage as unamb package and does exactly what you want. In particular, it contains

-- | Turn a binary commutative operation into one that tries both orders in
-- parallel. Useful when there are special cases that don't require
-- evaluating both arguments.
-- ...
parCommute :: (a -> a -> b) -> a -> a -> b

and also directly defines pand,por and other similar commutative functions, such that

pand undefined False   -> False
pand False undefined   -> False
Kingfish answered 14/6, 2014 at 20:7 Comment(3)
According to the documentation, amb evaluates its arguments "in separate threads". Does that mean it actually takes the time to create threads (and all the associated overhead) rather than using the spark pool?Deodand
Oh never mind, I get it. If the tasks are small enough to care about the overhead of using threads, then there's no reason to use unamb in the first place.Deodand
It's useful even for tasks that are fast "on one side" due to its strictness properties.Typewrite
A
6

This is provided by Conal Elliott's unamb package. It uses unsafePerformIO under the covers to evaluate both a && b and b && a on separate threads, and returns when either produces a result.

Apelles answered 14/6, 2014 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.