Skip to content

Commit

Permalink
Merge branch 'master' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
L-as committed Oct 27, 2022
2 parents 79ab116 + 77d0f72 commit 04d840f
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 12 deletions.
58 changes: 58 additions & 0 deletions Plutarch/Api/V1/AssocMap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ import Plutarch.TryFrom (PTryFrom (PTryFromExcess, ptryFrom'))
import Plutarch.Unsafe (punsafeCoerce, punsafeDowncast)
import PlutusCore qualified as PLC

import Data.Foldable (foldl')
import GHC.Exts (IsList (Item, fromList, toList))
import Prelude hiding (all, any, filter, lookup, null)

import Data.Proxy (Proxy (Proxy))
Expand Down Expand Up @@ -319,6 +321,62 @@ passertSorted =
pforgetSorted :: Term s (PMap 'Sorted k v) -> Term s (PMap g k v)
pforgetSorted v = punsafeDowncast (pto v)

{- | Given a 'Foldable' of key-value pairs, construct an unsorted 'PMap'.
Performs linearly with respect to its argument.
= Note
If there are duplicate keys in the input, the /last/ key will \'win\' in a
lookup.
-}
punsortedMapFromFoldable ::
forall (k :: PType) (v :: PType) (f :: Type -> Type) (s :: S).
(Foldable f, PIsData k, PIsData v) =>
f (Term s k, Term s v) ->
Term s (PMap 'Unsorted k v)
punsortedMapFromFoldable = pcon . PMap . foldl' go (pcon PNil)
where
go ::
forall (s' :: S).
Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v))) ->
(Term s' k, Term s' v) ->
Term s' (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
go acc (key, val) =
pcon . PCons (ppairDataBuiltin # pdata key # pdata val) $ acc

{- | Given a 'Foldable' of (not necessarily sorted) key-value pairs, construct a
'PMap' which is guaranteed sorted. Performs a linear number of ordered
insertions with respect to the length of its argument.
= Note
If there are duplicate keys, only the /last/ key-value pair will remain in
the result.
-}
psortedMapFromFoldable ::
forall (k :: PType) (v :: PType) (f :: Type -> Type) (s :: S).
(Foldable f, POrd k, PIsData k, PIsData v) =>
f (Term s k, Term s v) ->
Term s (PMap 'Sorted k v)
psortedMapFromFoldable = foldl' go pempty
where
go ::
forall (s' :: S).
Term s' (PMap 'Sorted k v) ->
(Term s' k, Term s' v) ->
Term s' (PMap 'Sorted k v)
go acc (key, val) = pinsert # key # val # acc

instance (PIsData k, PIsData v, POrd k) => IsList (Term s (PMap 'Unsorted k v)) where
type Item (Term s (PMap 'Unsorted k v)) = (Term s k, Term s v)
fromList = punsortedMapFromFoldable
toList = error "unimplemented"

instance (PIsData k, PIsData v, POrd k) => IsList (Term s (PMap 'Sorted k v)) where
type Item (Term s (PMap 'Sorted k v)) = (Term s k, Term s v)
fromList = psortedMapFromFoldable
toList = error "unimplemented"

instance
(POrd k, PIsData k, PIsData v, Semigroup (Term s v)) =>
Semigroup (Term s (PMap 'Sorted k v))
Expand Down
6 changes: 3 additions & 3 deletions Plutarch/Api/V1/Contexts.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ newtype PTxInfo (s :: S)
)
)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq, PShow)

instance DerivePlutusType PTxInfo where type DPTStrat _ = PlutusTypeData

Expand All @@ -75,7 +75,7 @@ newtype PScriptContext (s :: S)
)
)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq, PShow)

instance DerivePlutusType PScriptContext where type DPTStrat _ = PlutusTypeData

Expand All @@ -91,7 +91,7 @@ data PScriptPurpose (s :: S)
| PRewarding (Term s (PDataRecord '["_0" ':= PStakingCredential]))
| PCertifying (Term s (PDataRecord '["_0" ':= PDCert]))
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PEq)
deriving anyclass (PlutusType, PIsData, PEq, PShow)

instance DerivePlutusType PScriptPurpose where type DPTStrat _ = PlutusTypeData

Expand Down
2 changes: 1 addition & 1 deletion Plutarch/Api/V1/DCert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ data PDCert (s :: S)
| PDCertGenesis (Term s (PDataRecord '[]))
| PDCertMir (Term s (PDataRecord '[]))
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PEq, PPartialOrd, POrd)
deriving anyclass (PlutusType, PIsData, PEq, PPartialOrd, POrd, PShow)
instance DerivePlutusType PDCert where type DPTStrat _ = PlutusTypeData

instance PUnsafeLiftDecl PDCert where type PLifted PDCert = Plutus.DCert
Expand Down
5 changes: 3 additions & 2 deletions Plutarch/Api/V1/Scripts.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ deriving via (DerivePConstantViaBuiltin Plutus.Datum PDatum PData) instance PCon

newtype PRedeemer (s :: S) = PRedeemer (Term s PData)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PEq)
deriving anyclass (PlutusType, PIsData, PEq, PShow)
instance DerivePlutusType PRedeemer where type DPTStrat _ = PlutusTypeNewtype

instance PUnsafeLiftDecl PRedeemer where type PLifted PRedeemer = Plutus.Redeemer
Expand All @@ -49,7 +49,7 @@ deriving via (DerivePConstantViaBuiltin Plutus.DatumHash PDatumHash PByteString)

newtype PRedeemerHash (s :: S) = PRedeemerHash (Term s PByteString)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PEq, PPartialOrd, POrd)
deriving anyclass (PlutusType, PIsData, PEq, PPartialOrd, POrd, PShow)
instance DerivePlutusType PRedeemerHash where type DPTStrat _ = PlutusTypeNewtype

instance PUnsafeLiftDecl PRedeemerHash where type PLifted PRedeemerHash = Plutus.RedeemerHash
Expand All @@ -58,6 +58,7 @@ deriving via
instance
PConstantDecl Plutus.RedeemerHash


newtype PScriptHash (s :: S) = PScriptHash (Term s PByteString)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PEq, PPartialOrd, POrd, PShow)
Expand Down
4 changes: 2 additions & 2 deletions Plutarch/Api/V2/Contexts.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ newtype PScriptContext (s :: S)
)
)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq, PShow)

instance DerivePlutusType PScriptContext where type DPTStrat _ = PlutusTypeData

Expand Down Expand Up @@ -66,7 +66,7 @@ newtype PTxInfo (s :: S)
)
)
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq)
deriving anyclass (PlutusType, PIsData, PDataFields, PEq, PShow)

instance DerivePlutusType PTxInfo where type DPTStrat _ = PlutusTypeData

Expand Down
3 changes: 2 additions & 1 deletion docs/Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ As a preview, the bridge Plutarch provides between Haskell and UPLC looks someth
| *Haskell World* |
------------------------------------------------------
| Values with types like `Bool`, `Integer`, `Maybe a`|
| and regular Haskell functions like a -> b |
------------------------------------------------------
^ |
(functions like `plift`)--| |--(functions like `pconstant`)
(functions like `plift`)--| |--(functions like `pconstant` or `plam`)
| |
| v (`pcon`)
------------------------------------------------------- | -------------------------------------------------------
Expand Down
6 changes: 5 additions & 1 deletion docs/Introduction/Delay and Force.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ Plutarch, like UPLC, is strict by default; this is in contrast to Haskell, which
This behavior may be undesirable, for example, when one of two `Term`s are branched upon within an `if` statement. The Plutarch level function `pif'` is naturally strict in its arguments - and therefore evaluate both branches before even entering the function body.

```hs
pif' :: Term s (PBool :--> b :--> b :--> b)
-- obscuring the then-else part of the syntax, solely to make the Haskell- and Plutarch-versions look more alike
hif :: Bool -> a -> a -> a
hif cond whenTrue whenFalse = if cond then whenTrue else whenFalse

pif' :: Term s (PBool :--> pa :--> pa :--> pa)
pif' = plam hif
```

Expand Down
7 changes: 7 additions & 0 deletions docs/Introduction/Plutarch Terms/Plutarch Constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ These types deserve some explaination.

That is, if we ask `justTerm` what it will return when evaluated, it responds, "You should interpret the value I give you as either `Nothing` or `Just Integer`." Of course, we know that the result will always be `Just 3`; but this is the general mechanism to declare a function requiring a `Maybe`.

If you don't want to pretend to not know `x` during compile time, another example may be:

```hs
hPJustPInteger :: Term s PInteger -> Term s (PMaybe PInteger)
hPJustPInteger x = pcon (PJust x)
```

The `pcon` function is a method of the [`PCon` typeclass](./../../Typeclasses/PlutusType,%20PCon,%20and%20PMatch.md).

## Overloaded literals
Expand Down
2 changes: 1 addition & 1 deletion docs/Introduction/Plutarch Types.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PBool :: S -> Type

Thus, any time we see the kind `S -> Type`, we should mentally substitute its kind synonym `PType`. We reiterate: types of kind `PType`, should be considered as _tags_ on computation. They do not represent types of values in the same way as standard Haskell types.

The kind of basic types such as `Integer` in Haskell has the kind: `Type`; the corresponding "basic" kind in Plutarch is simply `PType`. Higher-kinded types in Haskell, such as `Maybe`, will kinds such as `Type -> Type`. In Plutarch, the corresponding kind is:
The kind of basic types such as `Integer` in Haskell has the kind: `Type`; the corresponding "basic" kind in Plutarch is simply `PType`. Higher-kinded types in Haskell, such as `Maybe`, will have kinds such as `Type -> Type`. In Plutarch, the corresponding kind is:

```hs
ghci> :k PMaybe
Expand Down
2 changes: 1 addition & 1 deletion docs/Usage/FFI.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ following table shows the correspondence between the two universes of types:
When it comes to user-defined types, you have a choice of passing their values
encoded as `Data` or directly. In the latter case, you'll have to declare your
type twice with two kinds: as a Haskell `Type` and as a Plutarch
`PType`. Futhermore, both types must be instances of `SOP.Generic`, as in this
`PType`. Furthermore, both types must be instances of `SOP.Generic`, as in this
example:

```haskell
Expand Down

0 comments on commit 04d840f

Please sign in to comment.