IntersectMBO / IntersectMBO/plutus

`ReadKnownIn DefaultUni term Int64` should extract the `Int` directly

Open
#7,501 1 comment 0 reactions 0 assignees View on GitHub
Internal Performance status: triaged
Dominant language
Haskell
Stars
1.6k
Forks
508
Avg merge
3d 10h
Merged PRs (30d)
22

Description

The instance is defined as

```haskell
instance KnownBuiltinTypeIn DefaultUni term Integer => ReadKnownIn DefaultUni term Int64 where
readKnown = readKnownAsInteger
```

where

```haskell
readKnownAsInteger
:: forall term a
. (KnownBuiltinTypeIn DefaultUni term Integer, Integral a, Bounded a, Typeable a)
=> term -> ReadKnownM a
readKnownAsInteger term =
inline readKnownConstant term >>= oneShot \(i :: Integer) ->
if fromIntegral (minBound :: a) <= i && i <= fromIntegral (maxBound :: a)
then pure $ fromIntegral i
else
throwError . operationalUnliftingError $ <...>
```

While `readKnownAsInteger` makes sense for most `Integral` types, it's very inefficient for `Int64` specifically, because all you actually need to convert an `Integer` to `Int64` on a 64-bit platform is to unwrap the latter from the `IS` constructor:

```haskell
-- If the value is small (i.e., fits into an 'Int'), the 'IS' constructor is
-- used. Otherwise 'IP' and 'IN' constructors are used to store a 'BigNat'
-- representing the positive or the negative value magnitude, respectively.
--
-- Invariant: 'IP' and 'IN' are used iff the value does not fit in 'IS'.
data Integer
= IS !Int# -- ^ iff value in @[minBound::'Int', maxBound::'Int']@ range
| IP !BigNat# -- ^ iff value in @]maxBound::'Int', +inf[@ range
| IN !BigNat# -- ^ iff value in @]-inf, minBound::'Int'[@ range
```

Currently the `ReadKnownIn DefaultUni term Int` instance is under the `#if WORD_SIZE_IN_BITS == 64` CPP pragma, but that one is guaranteed to be correct without the pragma if you just unwrap from the `IS` constructor and similarly `ReadKnownIn DefaultUni term Word` is guaranteed to be correct if you just use `readKnownAsInteger` there as nearly everywhere else, so I recommend doing it the other way around and deriving the instance for `Int64` from the `Int` one -- and placing the former under the CPP pragma.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.