user5610: Working on Week 2 Homework 1, I tried to define a new type DuBool. The following is the relevant portion of the code, with the more traditional version commented out immediately above each line that uses DuBool.
newtype DuBool = DuBool (Bool,Bool)
PlutusTx.unstableMakeIsData ''DuBool
--
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -> (Bool, Bool) -> ScriptContext -> Bool
mkValidator :: () -> DuBool -> ScriptContext -> Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (a,b) _ = traceIfFalse "Bools no match" $ a == b
mkValidator _ (DuBool d) _
    | a==b = True
    | otherwise = traceIfFalse "Bools no match" $ False
  where (a,b) = d
--
--
data Typed
instance Scripts.ValidatorTypes Typed where
-- Implement the instance!
    type instance DatumType Typed = ()
--    type instance RedeemerType Typed = (Bool,Bool)
    type instance RedeemerType Typed = DuBool
--
--
typedValidator :: Scripts.TypedValidator Typed
-- typedValidator = undefined -- FIX ME!
typedValidator = Scripts.mkTypedValidator @Typed
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||])
  where
--    wrap = Scripts.wrapValidator @() @(Bool,Bool)
    wrap = Scripts.wrapValidator @() @DuBool

This does compile in the repl error-free, and does compile and run in the playground simulator, but failure occurs with evaluation when the grab validation step occurs in the simulator, with


, Slot 2: 00000000-0000-4000-8000-000000000000 {Wallet W7ce8}:
            Contract instance stopped with error: "WalletError (ValidationError (ScriptFailure (EvaluationError [\"PT1\"] \"CekEvaluationFailure\")))" ]


I went back and attempted to edit the "type GiftSchema =" section to use DuBool, as follows:
type GiftSchema =
            Endpoint "give" Integer
--      .\/ Endpoint "grab" (Bool, Bool)
        .\/ Endpoint "grab" DuBool

and then the grab definition...
-- grab :: forall w s e. AsContractError e => (Bool, Bool) -> Contract w s e ()
grab :: forall w s e. AsContractError e => DuBool -> Contract w s e ()

But now compilation in the repl fails (sorry that the color and alignment here does not match what I see in the repl).


Prelude Ledger.Scripts PlutusTx> :l src/Week02/Homework1c_jwb.hs
[1 of 1] Compiling Week02.Homework1 ( src/Week02/Homework1c_jwb.hs, /Users/jwb/plutus/plutus-pioneer-program/code/week02/dist-newstyle/build/x86_64-osx/ghc-8.10.4.20210212/plutus-pioneer-program-week02-0.1.0.0/build/Week02/Homework1.o )
src/Week02/Homework1c_jwb.hs:117:13: error:
• No instance for (aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
DuBool)
arising from a use of ‘endpoint’
• In the expression: endpoint @"grab" grab
In an equation for ‘grab'’: grab' = endpoint @"grab" grab
In an equation for ‘endpoints’:
endpoints
= awaitPromise (give' select grab') >> endpoints
where
give' = endpoint @"give" give
grab' = endpoint @"grab" grab
|
117 |     grab' = endpoint @"grab" grab
|             ^^^^^^^^^^^^^^^^^^^^^
src/Week02/Homework1c_jwb.hs:119:1: error:
• No instance for (Schema.ToSchema DuBool)
arising from a use of ‘Playground.Schema.endpointsToSchemas’
• In the expression:
Playground.Schema.endpointsToSchemas
@((./) (Endpoint "give" Integer) (Endpoint "grab" DuBool))
In an equation for ‘schemas’:
schemas
= Playground.Schema.endpointsToSchemas
@((./) (Endpoint "give" Integer) (Endpoint "grab" DuBool))
|
119 | mkSchemaDefinitions ''GiftSchema
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
Prelude Ledger.Scripts PlutusTx>


It appears that the entire code as written (including what I am leaving out for brevity) can convert (Bool,Bool) to JSON, but not DuBool. I am wondering if there is a simple change, perhaps to the imports, {-# LANGUAGE ... #-}, instantiation, etc. that would incorporate this functionality?
Clearly this is not needed to "solve" homework 1 of week 2, but I do believe it is a valid programmatic approach that will be useful going forward. And I think I am very close. Thanks in advance!
=============================================================
Kurt Sys provided an extremely helpful partial answer. A few rounds of trial and error in the repl led me to this compiling and working-in-the-simulator solution. I've left a comment trail to help anyone else following along.


-- import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage, Generic, FromJSON, ToJSON, ToSchema)
--
-- newtype DuBool = DuBool (Bool,Bool)
data DuBool = DuBool
  {
    b1 :: Bool
   ,b2 :: Bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)
PlutusTx.unstableMakeIsData ''DuBool
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -> (Bool, Bool) -> ScriptContext -> Bool
mkValidator :: () -> DuBool -> ScriptContext -> Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (DuBool (a,b)) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (a,b) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (DuBool d) _
mkValidator _ (DuBool a b) _
    | a==b = True
    | otherwise = traceIfFalse "Bools no match" $ False
--  where (a,b) = d


Now I need to understand the difference between "data" and "newtype".

user5602: For homework1, you don't need to define a new type. That's what's done in homework2 :). Now, for defining a new data type (which is what you want):
data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  }

adding some type classes (implementing functions of some type classes) to it:
data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)

I think that should work fine.

5610: <p>Working on Week 2 Homework 1, I tried to define a new type DuBool. The following is the relevant portion of the code, with the more traditional version commented out immediately above each line that uses DuBool.</p>
<pre><code>newtype DuBool = DuBool (Bool,Bool)
PlutusTx.unstableMakeIsData ''DuBool
--
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -&gt; (Bool, Bool) -&gt; ScriptContext -&gt; Bool
mkValidator :: () -&gt; DuBool -&gt; ScriptContext -&gt; Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (a,b) _ = traceIfFalse &quot;Bools no match&quot; $ a == b
mkValidator _ (DuBool d) _
    | a==b = True
    | otherwise = traceIfFalse &quot;Bools no match&quot; $ False
  where (a,b) = d
--
--
data Typed
instance Scripts.ValidatorTypes Typed where
-- Implement the instance!
    type instance DatumType Typed = ()
--    type instance RedeemerType Typed = (Bool,Bool)
    type instance RedeemerType Typed = DuBool
--
--
typedValidator :: Scripts.TypedValidator Typed
-- typedValidator = undefined -- FIX ME!
typedValidator = Scripts.mkTypedValidator @Typed
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||])
  where
--    wrap = Scripts.wrapValidator @() @(Bool,Bool)
    wrap = Scripts.wrapValidator @() @DuBool
</code></pre>
<p>This does compile in the repl error-free, and does compile and run in the playground simulator, but failure occurs with evaluation when the grab validation step occurs in the simulator, with</p>
<blockquote>
<pre>
, Slot 2: 00000000-0000-4000-8000-000000000000 {Wallet W7ce8}:
            Contract instance stopped with error: "WalletError (ValidationError (ScriptFailure (EvaluationError [\"PT1\"] \"CekEvaluationFailure\")))" ]
</pre>
</blockquote>
<p>I went back and attempted to edit the &quot;type GiftSchema =&quot; section to use DuBool, as follows:</p>
<pre><code>type GiftSchema =
            Endpoint &quot;give&quot; Integer
--      .\/ Endpoint &quot;grab&quot; (Bool, Bool)
        .\/ Endpoint &quot;grab&quot; DuBool
</code></pre>
<p>and then the grab definition...</p>
<pre><code>-- grab :: forall w s e. AsContractError e =&gt; (Bool, Bool) -&gt; Contract w s e ()
grab :: forall w s e. AsContractError e =&gt; DuBool -&gt; Contract w s e ()
</code></pre>
<p>But now compilation in the repl fails (sorry that the color and alignment here does not match what I see in the repl).</p>
<blockquote>
<pre>
Prelude Ledger.Scripts PlutusTx> :l src/Week02/Homework1c_jwb.hs
[1 of 1] Compiling Week02.Homework1 ( src/Week02/Homework1c_jwb.hs, /Users/jwb/plutus/plutus-pioneer-program/code/week02/dist-newstyle/build/x86_64-osx/ghc-8.10.4.20210212/plutus-pioneer-program-week02-0.1.0.0/build/Week02/Homework1.o )
<p>src/Week02/Homework1c_jwb.hs:117:13: error:
• No instance for (aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
DuBool)
arising from a use of ‘endpoint’
• In the expression: endpoint @&quot;grab&quot; grab
In an equation for ‘grab'’: grab' = endpoint @&quot;grab&quot; grab
In an equation for ‘endpoints’:
endpoints
= awaitPromise (give' <code>select</code> grab') &gt;&gt; endpoints
where
give' = endpoint @&quot;give&quot; give
grab' = endpoint @&quot;grab&quot; grab
|
117 |     grab' = endpoint @&quot;grab&quot; grab
|             ^^^^^^^^^^^^^^^^^^^^^</p>
<p>src/Week02/Homework1c_jwb.hs:119:1: error:
• No instance for (Schema.ToSchema DuBool)
arising from a use of ‘Playground.Schema.endpointsToSchemas’
• In the expression:
Playground.Schema.endpointsToSchemas
@((./) (Endpoint &quot;give&quot; Integer) (Endpoint &quot;grab&quot; DuBool))
In an equation for ‘schemas’:
schemas
= Playground.Schema.endpointsToSchemas
@((./) (Endpoint &quot;give&quot; Integer) (Endpoint &quot;grab&quot; DuBool))
|
119 | mkSchemaDefinitions ''GiftSchema
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
Prelude Ledger.Scripts PlutusTx&gt;
</pre></p>
</blockquote>
<p>It appears that the entire code as written (including what I am leaving out for brevity) can convert (Bool,Bool) to JSON, but not DuBool. I am wondering if there is a simple change, perhaps to the imports, {-# LANGUAGE ... #-}, instantiation, etc. that would incorporate this functionality?</p>
<p>Clearly this is not needed to &quot;solve&quot; homework 1 of week 2, but I do believe it is a valid programmatic approach that will be useful going forward. And I think I am very close. Thanks in advance!</p>
<p>=============================================================</p>
<p>Kurt Sys provided an extremely helpful partial answer. A few rounds of trial and error in the repl led me to this compiling and working-in-the-simulator solution. I've left a comment trail to help anyone else following along.</p>
<blockquote>
<pre>
-- import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage, Generic, FromJSON, ToJSON, ToSchema)
--
-- newtype DuBool = DuBool (Bool,Bool)
data DuBool = DuBool
  {
    b1 :: Bool
   ,b2 :: Bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)
PlutusTx.unstableMakeIsData ''DuBool
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -> (Bool, Bool) -> ScriptContext -> Bool
mkValidator :: () -> DuBool -> ScriptContext -> Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (DuBool (a,b)) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (a,b) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (DuBool d) _
mkValidator _ (DuBool a b) _
    | a==b = True
    | otherwise = traceIfFalse "Bools no match" $ False
--  where (a,b) = d
</pre>
</blockquote>
<p>Now I need to understand the difference between &quot;data&quot; and &quot;newtype&quot;.</p>
 5602: <p>For homework1, you don't need to define a new type. That's what's done in homework2 :). Now, for defining a new data type (which is what you want):</p>
<pre><code>data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  }
</code></pre>
<p>adding some type classes (implementing functions of some type classes) to it:</p>
<pre><code>data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)
</code></pre>
<p>I think that should work fine.</p>
