-
Notifications
You must be signed in to change notification settings - Fork 500
Support mkNil for any builtin types
#7438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
mkNil for Bool and BuiltinByteStringmkNil for any builtin types
|
I made it so that now |
| | (tyCon, tyArg1, tyArg2) == (builtinPairTyCon, builtinDataTyCon, builtinDataTyCon) -> | ||
| pure $ PLC.mkConstant annMayInline ([] @(PLC.Data, PLC.Data)) | ||
| _ -> throwPlain $ CompilationError "'mkNil' applied to an unknown type" | ||
| | GHC.getName n == mkNilOpaqueName -> compileMkNil ty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even though we now match mkNil directly and have "OPAQUE" for mkNil, we still need mkNilOpaque because for some reason ghc would ignore OPAQUE and use mkNilOpaque anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| -> m (PIRTerm uni fun) | ||
| compileMkNil ty = | ||
| let | ||
| tyToUniverse :: GHC.Type -> Maybe (SomeTypeIn' PLC.DefaultUni) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a way to do this with existing SomeTypeIn? SomeTypeIn won't work because it has existential kind and it's impossible to force that to Type...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can avoid existentials altogether and do something like
withCompiledMkNil :: GHC.Type -> (forall a. PLC.DefaultUni (Esc a) -> m (PIRTerm uni fun)) -> m (PIRTerm uni fun)but I also think that your version is simpler, so who cares.
effectfully
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're my hero.
This was my original idea on how to make it work in the general case:
The only more or less reliable way I could think of is serializing the type at the type level into a
Symbol(to make sure it's fully done at compile time), requiring it to beKnownSymbol, then extracting the resultingStringin the compiler and parsing it back to get aDefaultUniobject. Sounds pretty crazy, but I can't think of another way of parsing a Haskell value back after embedding it into aCoreExpr.
But that's a lot of effort for something rather insignificant and your solution should be enough in most cases (I don't wanna think when it's not enough).
I'll check if I can it statically detectable that an instance is missing.
| {- | Identical to `SomeTypeIn` but without existential kind. | ||
| -} | ||
| type SomeTypeIn' :: (Kind.Type -> Kind.Type) -> Kind.Type | ||
| data SomeTypeIn' uni = forall a. SomeTypeIn' !(uni (PLC.Esc a)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could call it SomeStarIn or something. Just nitpicking obviously.
| -> m (PIRTerm uni fun) | ||
| compileMkNil ty = | ||
| let | ||
| tyToUniverse :: GHC.Type -> Maybe (SomeTypeIn' PLC.DefaultUni) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can avoid existentials altogether and do something like
withCompiledMkNil :: GHC.Type -> (forall a. PLC.DefaultUni (Esc a) -> m (PIRTerm uni fun)) -> m (PIRTerm uni fun)but I also think that your version is simpler, so who cares.
| | (tyCon, tyArg1, tyArg2) == (builtinPairTyCon, builtinDataTyCon, builtinDataTyCon) -> | ||
| pure $ PLC.mkConstant annMayInline ([] @(PLC.Data, PLC.Data)) | ||
| _ -> throwPlain $ CompilationError "'mkNil' applied to an unknown type" | ||
| | GHC.getName n == mkNilOpaqueName -> compileMkNil ty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import Data.Map qualified as Map | ||
| import Data.Text qualified as T | ||
|
|
||
| {- | Identical to `SomeTypeIn` but without existential kind. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elaborate why the existential kind is problematic?

You can now use
PlutusTx.Builtins.Opaque.mkNil @BoolandmkNil @BuiltinByteString.This doesn't add support for arbitrarily nested array. Only adds support for
BoolandByteString.I'm figuring out making this work with any subtype of default universe, so please don't merge yet