Skip to content
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

Fix "un-rolling" a list type. #6165

Merged
merged 2 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions plutus-tx/src/PlutusTx/Blueprint/Definition/Unroll.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import GHC.TypeLits qualified as GHC
import PlutusTx.Blueprint.Class (HasSchema)
import PlutusTx.Blueprint.Definition.Id as DefinitionId (AsDefinitionId (..))
import PlutusTx.Blueprint.Definition.Internal (Definitions (..), addDefinition, definition)
import PlutusTx.Builtins.Internal (BuiltinByteString, BuiltinData, BuiltinList, BuiltinString,
BuiltinUnit)
import PlutusTx.Builtins.Internal (BuiltinByteString, BuiltinData, BuiltinList, BuiltinPair,
BuiltinString, BuiltinUnit)

----------------------------------------------------------------------------------------------------
-- Functionality to "unroll" types. -- For more context see Note ["Unrolling" types] -----------
Expand Down Expand Up @@ -89,8 +89,12 @@ type family Unroll (p :: Type) :: [Type] where
Unroll BuiltinData = '[BuiltinData]
Unroll BuiltinUnit = '[BuiltinUnit]
Unroll BuiltinString = '[BuiltinString]
Unroll (BuiltinList a) = Prepend (BuiltinList a) (GUnroll (Rep a))
Unroll (BuiltinList a) = Unroll a
Unroll (BuiltinPair a b) = Unroll a ++ Unroll b
Unroll BuiltinByteString = '[BuiltinByteString]
Unroll [a] = Unroll a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this violate the invariant that the result needs to contain the original type as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a test showing that original type is indeed contained in the un-rolling. The RHS Unroll a will make sure that a is added to the un-rolling, as long as its not a list itself.

Unroll (a, b) = Unroll a ++ Unroll b
Unroll (Maybe a) = Unroll a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I still have no idea why this is desired rather than the Prepend thing. I do remember our discussion about lists, pairs etc being an inherent part of a schema, but what if it's a list of lists, is that now "user-space"? And I'm failing to understand how this logic maps onto the #list, #pair etc built-in types as per the CIP.

Sorry for being useless! Maybe the reviewers of the original blueprint PR would know better, CC'ing @kwxm @zliu41.

Unroll p = Prepend p (GUnroll (Break (NoGeneric p) (Rep p)))

-- | Detect stuck type family: https://blog.csongor.co.uk/report-stuck-families/#custom-type-errors
Expand Down
24 changes: 23 additions & 1 deletion plutus-tx/test/Blueprint/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import PlutusTx.Blueprint.Definition (AsDefinitionId, Definitions, Unroll, Unrol
Unrollable (..))
import PlutusTx.Blueprint.Schema (Schema (..))
import PlutusTx.Blueprint.Schema.Annotation (emptySchemaInfo)
import PlutusTx.Builtins (BuiltinData)
import PlutusTx.Builtins.Internal (BuiltinData, BuiltinList, BuiltinPair, BuiltinUnit)
import PlutusTx.IsData ()

----------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -74,6 +74,9 @@ testUnrollNop = Refl
testUnrollBaz :: Unroll Baz :~: [Baz, Integer]
testUnrollBaz = Refl

testUnrollListBaz :: Unroll [Baz] :~: [Baz, Integer]
testUnrollListBaz = Refl

testUnrollZap :: Unroll Zap :~: [Zap, Nop, Integer, Bool]
testUnrollZap = Refl

Expand All @@ -91,3 +94,22 @@ definitions = unroll @(UnrollAll '[Foo])

testUnrollDat :: Unroll Dat :~: '[Dat, BuiltinData]
testUnrollDat = Refl

testUnrollList :: Unroll [Bool] :~: '[Bool]
testUnrollList = Refl

testUnrollNestedLists :: Unroll [[[Bool]]] :~: '[Bool]
testUnrollNestedLists = Refl

testUnrollPair :: Unroll (Integer, Bool) :~: '[Bool, Integer]
testUnrollPair = Refl

testUnrollBuiltinPair :: Unroll (BuiltinPair Integer Bool) :~: '[Bool, Integer]
testUnrollBuiltinPair = Refl

testUnrollBuiltinList
:: Unroll (BuiltinList (BuiltinPair Bool BuiltinUnit)) :~: '[BuiltinUnit, Bool]
testUnrollBuiltinList = Refl
Unisay marked this conversation as resolved.
Show resolved Hide resolved

testUnrollMaybe :: Unroll (Maybe Bool) :~: '[Bool]
testUnrollMaybe = Refl