Skip to content

Commit ddb2a4d

Browse files
committed
Make the Tx.&& and Tx.|| short-circuit also in Haskell
1 parent 9f7aaa6 commit ddb2a4d

File tree

5 files changed

+35
-2
lines changed

5 files changed

+35
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### Changed
2+
3+
- Made the (&&) and (||) operators short-circuit also in the Haskell side.
4+
uplc code is unaffected and is already short-circuiting.

plutus-tx/plutus-tx.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ test-suite plutus-tx-test
208208
Blueprint.Definition.Spec
209209
Blueprint.Spec
210210
List.Spec
211+
Bool.Spec
211212
Rational.Laws
212213
Rational.Laws.Additive
213214
Rational.Laws.Construction

plutus-tx/src/PlutusTx/Bool.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,35 @@ import Prelude (Bool (..), otherwise)
1010

1111
-- `(&&)` and `(||)` are handled specially in the plugin to make sure they can short-circuit.
1212
-- See Note [Lazy boolean operators] in the plugin.
13+
-- In the Haskell-side, we are using `default-extensions: Strict` throughout PlutusTx,
14+
-- which means that we have to sure that the second argument is lazy to short-circuit the `(&&)` and `(||)`.
1315

1416
{-| Logical AND. Short-circuits if the first argument evaluates to `False`.
1517
1618
>>> True && False
1719
False
20+
21+
>>> False && error ()
22+
False
1823
-}
1924
infixr 3 &&
2025

2126
(&&) :: Bool -> Bool -> Bool
22-
(&&) l r = if l then r else False
27+
(&&) l ~r = if l then r else False
2328
{-# OPAQUE (&&) #-}
2429

2530
{-| Logical OR. Short-circuits if the first argument evaluates to `True`.
2631
2732
>>> True || False
2833
True
34+
35+
>>> True || error ()
36+
True
2937
-}
3038
infixr 2 ||
3139

3240
(||) :: Bool -> Bool -> Bool
33-
(||) l r = if l then True else r
41+
(||) l ~r = if l then True else r
3442
{-# OPAQUE (||) #-}
3543

3644
{-| Logical negation

plutus-tx/test/Bool/Spec.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Bool.Spec (boolTests) where
2+
3+
import PlutusTx.Builtins as Tx
4+
import PlutusTx.Bool qualified as Tx
5+
6+
import Prelude (($))
7+
import Test.Tasty
8+
import Test.Tasty.HUnit
9+
10+
boolTests :: TestTree
11+
boolTests =
12+
testGroup
13+
"PlutusTx.Bool tests"
14+
-- in uplc the &&,|| are treated specially to short-circuit
15+
-- this makes sures that the Haskell counterparts also short-circuit
16+
[ testCase "shortcircuit_&&" $ Tx.False Tx.&& Tx.error () @?= Tx.False
17+
, testCase "shortcircuit_||" $ Tx.True Tx.&& Tx.error () @?= Tx.True
18+
]

plutus-tx/test/Spec.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Hedgehog (MonadGen, Property, PropertyT, annotateShow, assert, forAll, pr
1919
import Hedgehog.Gen qualified as Gen
2020
import Hedgehog.Range qualified as Range
2121
import List.Spec (listTests)
22+
import Bool.Spec (boolTests)
2223
import PlutusCore.Data (Data (B, Constr, I, List, Map))
2324
import PlutusTx.Enum (Enum (..))
2425
import PlutusTx.Numeric (negate)
@@ -45,6 +46,7 @@ tests =
4546
, bytestringTests
4647
, enumTests
4748
, listTests
49+
, boolTests
4850
, lawsTests
4951
, Show.Spec.propertyTests
5052
, Show.Spec.goldenTests

0 commit comments

Comments
 (0)