Как выполнить параллельное "короткое замыкание" с "и" и "или",

Имеет ли haskell параллельный метод "и"

parAnd :: Bool -> Bool -> Bool

такое, что

(a `parAnd` b)

приведет к параллельной оценке a и b и возвращает false, как только a или b оценит значение false (и не дожидается другого)?

Есть ли способ реализовать такую ​​вещь?

Ответ 1

Обычно это невозможно. Вы можете сделать что-то вроде

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

но если b оценивается как False, a все еще полностью оценивается.

Однако это возможно с помощью оператора однозначного выбора, созданного Conal Elliott для реализации функционального реактивного программирования (FRP). Он доступен в Hackage как unamb и делает именно то, что вы хотите. В частности, он содержит

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

а также непосредственно определяет pand, por и другие подобные коммутативные функции, такие, что

pand undefined False   -> False
pand False undefined   -> False

Ответ 2

Это предоставляется Conal Elliott пакет unamb. Он использует unsafePerformIO под обложками для оценки как a && b, так и b && a в отдельных потоках и возвращает, когда либо производит результат.