1
1
{-# LANGUAGE AllowAmbiguousTypes #-}
2
+ {-# LANGUAGE LiberalTypeSynonyms #-}
2
3
{-# LANGUAGE OverloadedLists #-}
3
4
{-# LANGUAGE UndecidableInstances #-}
4
5
{-# OPTIONS_GHC -Wno-orphans #-}
5
-
6
- module LambdaBuffers.Runtime.Plutarch (PEither (.. ), PAssetClass , PMap , PChar , PSet , PValue , ptryFromPAsData , PMaybe (.. ), pcon ) where
6
+ {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
7
+
8
+ module LambdaBuffers.Runtime.Plutarch (
9
+ PEither (.. ),
10
+ PAssetClass ,
11
+ PMap ,
12
+ PChar ,
13
+ PSet ,
14
+ PValue ,
15
+ ptryFromPAsData ,
16
+ PMaybe (.. ),
17
+ pcon ,
18
+ PList (.. ),
19
+ caseList ,
20
+ pcons ,
21
+ pnil ,
22
+ ) where
7
23
8
24
import Data.Functor.Const (Const )
9
25
import GHC.Generics (Generic )
10
26
import GHC.TypeLits qualified as GHC
27
+ import LambdaBuffers.Runtime.Plutarch.LamVal (pfromPlutusDataPTryFrom )
11
28
import LambdaBuffers.Runtime.Plutarch.LamVal qualified as LamVal
12
29
import Plutarch (
13
30
PType ,
@@ -41,6 +58,14 @@ import Plutarch.Reducible (Reduce)
41
58
import Plutarch.TryFrom (PTryFrom (PTryFromExcess , ptryFrom' ))
42
59
import Plutarch.Unsafe (punsafeCoerce )
43
60
61
+ {- | PList because PBuiltinList misses `PAsData` on its constituents which causes type errors when used.
62
+ TODO(bladyjoker): Upstream these changes or fix PBuiltinList.
63
+ -}
64
+ newtype PList (a :: PType ) (s :: S )
65
+ = PList (Term s (PBuiltinList (PAsData a )))
66
+ deriving stock (Generic )
67
+ deriving anyclass (Pl.PShow )
68
+
44
69
-- | PAssetClass missing from Plutarch.
45
70
type PAssetClass = Plutarch.Api.V1. PTuple Plutarch.Api.V1. PCurrencySymbol Plutarch.Api.V1. PTokenName
46
71
@@ -53,6 +78,9 @@ type PValue = Plutarch.Api.V1.PValue 'Plutarch.Api.V1.Sorted 'Plutarch.Api.V1.No
53
78
-- | Not implemented.
54
79
data PChar (s :: S ) = PChar
55
80
81
+ -- | Not implemented.
82
+ data PSet (a :: PType ) (s :: S ) = PSet
83
+
56
84
-- | PEither missing from Plutarch.
57
85
data PEither (a :: PType ) (b :: PType ) (s :: S )
58
86
= PLeft (Term s (PAsData a ))
@@ -76,6 +104,7 @@ data PFoo (a :: PType) (s :: S)
76
104
(Term s (PAsData (PEither a a )))
77
105
(Term s (PAsData PAssetClass ))
78
106
(Term s (PAsData (PFoo a )))
107
+ (Term s (PAsData (PList a )))
79
108
deriving stock (Generic )
80
109
deriving anyclass (Pl.PShow )
81
110
@@ -136,9 +165,14 @@ instance PlutusType (PEither a b) where
136
165
(const perror)
137
166
pd
138
167
168
+ instance PlutusType (PList a ) where
169
+ type PInner (PList a ) = (PBuiltinList (PAsData a ))
170
+ pcon' (PList x) = x
171
+ pmatch' x f = f (PList x)
172
+
139
173
instance PlutusType (PFoo a ) where
140
174
type PInner (PFoo a ) = PData
141
- pcon' (PFoo i b bs may eit ac foo) =
175
+ pcon' (PFoo i b bs may eit ac foo xs ) =
142
176
LamVal. listData
143
177
[ LamVal. toPlutusData i
144
178
, LamVal. toPlutusData b
@@ -147,6 +181,7 @@ instance PlutusType (PFoo a) where
147
181
, LamVal. toPlutusData eit
148
182
, LamVal. toPlutusData ac
149
183
, LamVal. toPlutusData foo
184
+ , LamVal. toPlutusData xs
150
185
]
151
186
pmatch' pd f =
152
187
f
@@ -158,6 +193,7 @@ instance PlutusType (PFoo a) where
158
193
(LamVal. pfromPlutusDataPlutusType # pd)
159
194
(LamVal. pfromPlutusDataPlutusType # pd)
160
195
(LamVal. pfromPlutusDataPlutusType # pd)
196
+ (LamVal. pfromPlutusDataPlutusType # pd)
161
197
)
162
198
163
199
-- PTryFrom instances.
@@ -241,6 +277,20 @@ instance (PTryFrom PData (PAsData a)) => PTryFrom PData (PAsData (PMaybe a)) whe
241
277
, ()
242
278
)
243
279
280
+ instance PTryFrom PData (PAsData a ) => PTryFrom PData (PAsData (PList a )) where
281
+ type PTryFromExcess PData (PAsData (PList a )) = Const ()
282
+ ptryFrom' pd f =
283
+ f
284
+ ( LamVal. casePlutusData
285
+ (const $ const perror)
286
+ ( \ xs -> pcon $ PList $ Pl. pmap # pfromPlutusDataPTryFrom # xs
287
+ )
288
+ (const perror)
289
+ (const perror)
290
+ pd
291
+ , ()
292
+ )
293
+
244
294
instance (PTryFrom PData (PAsData a )) => PTryFrom PData (PFoo a ) where
245
295
type PTryFromExcess PData (PFoo a ) = Const ()
246
296
ptryFrom' = ptryFromPAsData
@@ -504,7 +554,7 @@ instance PTryFrom PData (PAsData Plutarch.Api.V2.PTxOut) where
504
554
, ()
505
555
)
506
556
507
- -- FIXME (bladyjoker): This is used above and it's a hack because something is off with PMaybeData instances.
557
+ -- HACK (bladyjoker): This is used above and it's a hack because something is off with PMaybeData instances.
508
558
maybeToMaybe :: Term s (PAsData (PMaybe a ) :--> PAsData (PMaybeData a ))
509
559
maybeToMaybe =
510
560
phoistAcyclic $
@@ -581,6 +631,7 @@ instance (PTryFrom PData (PAsData a)) => PTryFrom PData (PAsData (PFoo a)) where
581
631
(LamVal. pfromPlutusDataPTryFrom # pd)
582
632
(LamVal. pfromPlutusDataPTryFrom # pd)
583
633
(LamVal. pfromPlutusDataPTryFrom # pd)
634
+ (LamVal. pfromPlutusDataPTryFrom # pd)
584
635
, ()
585
636
)
586
637
@@ -598,9 +649,6 @@ instance GHC.TypeError ('GHC.Text "LambdaBuffers Prelude.Char not implemented")
598
649
instance GHC. TypeError ('GHC.Text " LambdaBuffers Prelude.Char not implemented" ) => PEq PChar where
599
650
(#==) _l _r = error " unreachable"
600
651
601
- -- | Not implemented.
602
- data PSet (a :: PType ) (s :: S ) = PSet
603
-
604
652
instance GHC. TypeError ('GHC.Text " LambdaBuffers Prelude.Set not implemented" ) => PlutusType (PSet a ) where
605
653
type PInner (PSet a ) = PData
606
654
pcon' PSet = error " unreachable"
@@ -626,6 +674,10 @@ instance PIsData (PEither a b) where
626
674
pdataImpl = punsafeCoerce
627
675
pfromDataImpl = punsafeCoerce
628
676
677
+ instance PIsData (PList a ) where
678
+ pdataImpl = punsafeCoerce
679
+ pfromDataImpl = punsafeCoerce
680
+
629
681
instance PEq (PFoo a ) where
630
682
(#==) l r = pdata l #== pdata r
631
683
@@ -635,5 +687,23 @@ instance PEq (PMaybe a) where
635
687
instance PEq (PEither a b ) where
636
688
(#==) l r = pdata l #== pdata r
637
689
690
+ instance PEq (PList a ) where
691
+ (#==) l r = Pl. plistEquals # Pl. pto l # Pl. pto r
692
+
638
693
pcon :: (PlutusType a , PIsData a ) => a s -> Term s (PAsData a )
639
694
pcon = pdata . Pl. pcon
695
+
696
+ {- | PListLike instance was a problem for PList, so this is done instead.
697
+
698
+ TODO(bladyjoker): Upstream with PList and plan to remove.
699
+ -}
700
+ caseList :: (PIsData a ) => (Term s a -> Term s (PList a ) -> Term s r ) -> Term s r -> Term s (PList a ) -> Term s r
701
+ caseList consCase nilCase ls = pmatch (Pl. pto ls) $ \ case
702
+ Pl. PCons x xs -> consCase (Pl. pfromData x) (Pl. pcon $ PList xs)
703
+ Pl. PNil -> nilCase
704
+
705
+ pcons :: PIsData a => Term s (a :--> (PList a :--> PList a ))
706
+ pcons = phoistAcyclic $ plam $ \ x xs -> Pl. pcon $ PList (Pl. pcons # Pl. pdata x # Pl. pto xs)
707
+
708
+ pnil :: Term s (PList a )
709
+ pnil = Pl. pcon $ PList $ Pl. pcon Pl. PNil
0 commit comments