Skip to content

Commit

Permalink
fix pstruct method infer
Browse files Browse the repository at this point in the history
  • Loading branch information
michele-nuzzi committed Feb 13, 2024
1 parent d3d5e58 commit fc75b91
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 8 deletions.
4 changes: 2 additions & 2 deletions packages/onchain/src/pluts/PTypes/PStruct/pstruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export type PStruct<SDef extends StructDefinition, SMethods extends Methods> = {
/**
* @deprecated
*/
readonly termType: StructT<SDef>;
readonly type: StructT<SDef>;
readonly termType: StructT<SDef,SMethods>;
readonly type: StructT<SDef,SMethods>;

readonly fromDataTerm: TermFn<[PData],PStruct<SDef, SMethods>>
fromData: ( data: Term<PData> ) => Term<PStruct<SDef, SMethods>>;
Expand Down
57 changes: 57 additions & 0 deletions packages/onchain/src/pluts/lib/std/PMaybe/PListMaybe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { PDataRepresentable } from "../../../PType/PDataRepresentable";
import type { PBool, PDelayed, PList, TermFn } from "../../../PTypes";
import { PAlias, palias } from "../../../PTypes/PAlias/palias";
import { TermType, list, lam, bool, delayed, AliasT, ListT, ToPType } from "../../../type_system";
import { punsafeConvertType } from "../../punsafeConvertType";
import { pfn } from "../../pfn";
import { phoist } from "../../phoist";
import { perror } from "../../perror";
import { pforce } from "../../pforce";
import { pdelay } from "../../pdelay";
import { pisEmpty } from "../../builtins/list";
import { pif, pstrictIf } from "../../builtins/bool";

export type ListMaybeT<T extends TermType> =
AliasT<ListT<T>,{
isNothing: TermFn<[ PList<ToPType<T>> ], PBool>,
unwarpOrFail: TermFn<[ PList<ToPType<T>> ], ToPType<T>>
unwarpOrElse: TermFn<[ PList<ToPType<T>>, PDelayed<ToPType<T>> ], ToPType<T>>
}>

export type PListMaybeT<PTy extends PDataRepresentable> =
PAlias<PList<PTy>,{
isNothing: TermFn<[ PList<PTy> ], PBool>,
unwarpOrFail: TermFn<[ PList<PTy> ], PTy>
unwarpOrElse: TermFn<[ PList<PTy>, PDelayed<PTy> ], PTy>
}>

export function PListMaybe<T extends TermType>(tyArg: T): PListMaybeT<ToPType<T>>
{
return palias(
list( tyArg ),
self_t => {

return {
isNothing: punsafeConvertType( pisEmpty, lam( self_t, bool ) ),
unwrapOrFail: phoist(
pfn([ self_t ], tyArg)
( self =>
pif( tyArg ).$( pisEmpty.$( self ) )
.then( perror( tyArg ) )
.else( self.head )
)
),
unwarpOrElse: phoist(
pfn([ self_t, delayed( tyArg ) ], tyArg)
(( self, weDontLikeThat ) =>
pforce(
pstrictIf( delayed( tyArg ) ).$( pisEmpty.$( self ) )
.$( weDontLikeThat )
.$( pdelay( self.head ) )
)
)
)
}
}
) as any;
}
3 changes: 2 additions & 1 deletion packages/onchain/src/pluts/lib/std/PMaybe/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./PMaybe";
export * from "./PMaybe";
export * from "./PListMaybe";
4 changes: 2 additions & 2 deletions packages/onchain/src/pluts/lib/std/UtilityTerms/TermStruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ export type TermStruct<SDef extends StructDefinition, SMethods extends Methods>
} : {}
) &
LiftMethods<
FilterMethodsByInput<SMethods,PStruct<SDef, any>>
FilterMethodsByInput<SMethods,PStruct<SDef, {}>>
> &
MethodsAsTerms<
FilterMethodsByInput<SMethods,PStruct<SDef, any>>
FilterMethodsByInput<SMethods,PStruct<SDef, {}>>
>

const hoisted_getFields = new IRHoisted(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { Machine } from "@harmoniclabs/plutus-machine"
import { pstruct } from "../../../../PTypes"
import { bs, int } from "../../../../type_system"
import { pmatch, pstruct } from "../../../../PTypes"
import { bs, int, list, unit } from "../../../../type_system"
import { plet } from "../../../plet"
import { pDataB, pDataI } from "../../data"
import { pInt } from "../../int"
import { passert } from "../../passert"
import { pList } from "../../list/const"
import { PTxOut } from "../../../../API/V2/Tx/PTxOut"
import { phoist } from "../../../phoist"
import { PTxInInfo } from "../../../../API/V2/Tx/PTxInInfo"
import { pfn } from "../../../pfn"
import { UtilityTermOf } from "../addUtilityForType"
import { pmakeUnit } from "../../unit/pmakeUnit"
import { TermStruct } from "../TermStruct"

const SingleCtor = pstruct({
SingleCtor: {
Expand Down Expand Up @@ -33,5 +42,102 @@ describe("dot notation", () => {
)
);

});

test("not really", () => {

// more than 3 inputs not allowed
const SwapInputIndexes = pstruct({
Single: { index: int },
Double: { fst: int, snd: int },
Triple: { fst: int, snd: int, trd: int }
}, self_t => {
const pListTxOut = pList( PTxOut.type );

// typescript does not infer the methods (plu-ts 0.6.6)
// to be fixed
// workaroud: define a separate function
const resolveSwapInputIndexesInputs = phoist(
pfn([ self_t, list( PTxInInfo.type ) ], list( PTxOut.type ))
( (self, inputs) =>
pmatch( self )
.onSingle(({ index }) => pListTxOut([ inputs.at( index ).resolved ]) )
.onDouble(({ fst, snd }) =>
plet(
// assert fst and snd are not equal
passert.$( fst.lt( snd ) )
).in( _ =>
pListTxOut([
inputs.at( fst ).resolved,
inputs.at( snd ).resolved,
])
)
)
.onTriple(({ fst, snd, trd }) =>
plet(
// assert fst, snd and trd are not equal
passert.$( fst.lt( snd ).and( snd.lt( trd ) ) )
).in( _ =>
pListTxOut([
inputs.at( fst ).resolved,
inputs.at( snd ).resolved,
inputs.at( trd ).resolved
])
)
)
)
);

const resolveSwapInputIndexesOutputs = phoist(
pfn([ self_t, list( PTxOut.type ) ], list( PTxOut.type ))
( (self, inputs) =>
pmatch( self )
.onSingle(({ index }) => pListTxOut([ inputs.at( index ) ]) )
.onDouble(({ fst, snd }) =>
plet(
// assert fst and snd are not equal
passert.$( fst.lt( snd ) )
).in( _ =>
pListTxOut([
inputs.at( fst ),
inputs.at( snd ),
])
)
)
.onTriple(({ fst, snd, trd }) =>
plet(
// assert fst, snd and trd are not equal
passert.$( fst.lt( snd ).and( snd.lt( trd ) ) )
).in( _ =>
pListTxOut([
inputs.at( fst ),
inputs.at( snd ),
inputs.at( trd )
])
)
)
)
);

const getSwapInputIndexesLength = phoist(
pfn([ self_t ], int)
( userIn => userIn.raw.index.add( 1 ) )
);

return {
resolveInputs: resolveSwapInputIndexesInputs,
resolveOutputs: resolveSwapInputIndexesOutputs,
length: getSwapInputIndexesLength
};
});

pfn([ SwapInputIndexes.type ], unit)
( idxs => {

idxs.length
return pmakeUnit();
})


})
})
3 changes: 2 additions & 1 deletion packages/onchain/src/pluts/lib/std/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export * from "./pair";
export * from "./stdEq";
export * from "./PMaybe";
export * from "./combinators";
export * from "./UtilityTerms";
export * from "./UtilityTerms";
export * from "./passert";
21 changes: 21 additions & 0 deletions packages/onchain/src/pluts/lib/std/passert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { bool, str, unit } from "../../type_system/types";
import { pif } from "../builtins/bool";
import { ptraceError } from "../builtins/ptrace";
import { perror } from "../perror";
import { pfn } from "../pfn";
import { phoist } from "../phoist";
import { pmakeUnit } from "./unit/pmakeUnit";

export const passert = phoist(
pfn([ bool ], unit)
( condition => pif( unit ).$( condition ).then( pmakeUnit() ).else( perror( unit ) ) )
);

export const passertOrTrace = phoist(
pfn([ str, bool ], unit)
( (msg, condition) =>
pif( unit ).$( condition )
.then( pmakeUnit() )
.else( ptraceError( unit ).$( msg ) )
)
);

0 comments on commit fc75b91

Please sign in to comment.