<p>I don't know if this is what you expect but there are three ways to get rid of warnings:</p>
<ol>
<li>add <code>{-# LANGUAGE MonoLocalBinds     #-}</code>, like the warning hints</li>
<li>don't give a type for <code>payTo</code> and let Haskell infer it</li>
<li>if things worked before, the body of <code>payTo</code> was fine in the <code>EmulatorTrace</code> monad, so you could go for <code>payTo :: PaymentPubKeyHash -&gt; Integer -&gt; EmulatorTrace ()</code></li>
</ol>
<p>I'm not particularly fond of the idea of moving the function in a <code>where</code> clause if it depends on something you obtain in the body of the bigger function. You could consider adding another parameter and passing <code>contract1</code> as an argument, and then you can move it to <code>where</code>.</p>

CC BY-SA 4.0
2022-02-13T14:21:39.333Z
Allright, thanks. Well, I just wanted to get rid of the warning and understand why it's there. So, seeing your solutions: 1. what does it mean (`MonoLocalBinds`)? 2. I try to understand the types passed everywhere. Is there no way I can give the right type signature? 3. The body was fine, but moving it to the where, makes in different (it's a different type in the do-bindings vs in the were clause.
That being said, it makes more sense to keep in the `let`-binding? (Just trying to figure out the Haskell type system and monads and do-bindings)
Kurt Sys
CC BY-SA 4.0
2022-02-13T14:53:02.080Z
1. a Haskell extension meant to infer less polymorphic types. Details here: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/let_generalisation.html. 2. I'd say using `EmulatorTrace ()` for the result is the right type signature. The type you use is more general: `(Member RunContract effs) => ... -> Eff effs ()` can be specialized to `Eff '[StartContract, RunContract, Assert, Waiting, EmulatorControl, EmulatedWalletAPI, LogMsg String, Error EmulatorRuntimeError] ()`, which is `EmulatorTrace ()`, because RunContract is in the list of effects for EmulatorTrace thus the condition holds.
Mihai Codescu
CC BY-SA 4.0
2022-02-13T15:05:36.733Z
And 3, you use `contract1` in the body of `payTo` and if you move `payTo` to the `where` clause, `contract1` is no longer in scope, as it is local to the body of `payTrace`. Either leave `payTo` in the `let`-binding or make `payTo :: ContractHandle w s e -> PaymentPubKeyHash -> Integer -> EmulatorTrace ()`, move it to `where` and add `contract1` to the calls of `payTo` in the body of `payTrace`.
Mihai Codescu
CC BY-SA 4.0
2022-02-12T16:34:48.790Z
2022-02-12T16:34:48.790Z
Mihai Codescu
<p>In homework of week4, I refactored my solution:</p>
<pre><code>payTrace :: Integer -&gt; Integer -&gt; EmulatorTrace ()
payTrace payment1 payment2 =  do
contract1 &lt;- activateContractWallet (knownWallet 1) payContract
let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
callEndpoint @&quot;pay&quot; contract1 $ PayParams
   {
       ppRecipient = pkh2
   ,   ppLovelace = payment1
   }
void $ Emulator.waitNSlots 1
callEndpoint @&quot;pay&quot; contract1 $ PayParams
   {
       ppRecipient = pkh2
   ,   ppLovelace = payment2
   }
void $ Emulator.waitNSlots 1
</code></pre>
<p>to:</p>
<pre><code>payTrace :: Integer -&gt; Integer -&gt; EmulatorTrace ()
payTrace payment1 payment2 =  do
contract1 &lt;- activateContractWallet (knownWallet 1) payContract
let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
    payTo :: (Member RunContract effs) =&gt; PaymentPubKeyHash -&gt; Integer -&gt; Eff effs ()
    payTo pkh amount = callEndpoint @&quot;pay&quot; contract1 $ PayParams
       {
           ppRecipient = pkh
       ,   ppLovelace = amount
       }
payTo pkh2 payment1
void $ Emulator.waitNSlots 1
payTo pkh2 payment2
void $ Emulator.waitNSlots 1
</code></pre>
<p>(<a href="https://gitlab.com/moment-4/courses/plutus-pioneer/plutus-pioneer-program/-/blob/week04/code/week04/src/Week04/Homework.hs" rel="nofollow noreferrer">https://gitlab.com/moment-4/courses/plutus-pioneer/plutus-pioneer-program/-/blob/week04/code/week04/src/Week04/Homework.hs</a>)</p>
<p>However, there are still 2 things I don't like about my current solution:</p>
<ol>
<li><p>I'd prefer to put the <code>payTo</code> function in the where clause, but that doesn't seem to work properly (although I think I'm close thanks to Luis (<a href="https://discord.com/channels/826816523368005654/834340082273878046/942064349831381042" rel="nofollow noreferrer">https://discord.com/channels/826816523368005654/834340082273878046/942064349831381042</a>). How would one define it in the where clause? (The solution of Luis put me on the right track, but I still can't get it right)</p>
</li>
<li><p>I still get compiler warnings about the type. How to define the type of the function properly, so I can get rid of the warnings as well?</p>
</li>
</ol>
<pre><code>src/Week04/Homework.hs:46:18: warning: [-Wsimplifiable-class-constraints]
    • The constraint ‘Member RunContract effs’ matches
        instance (Data.OpenUnion.Internal.FindElem t r,
                  Data.OpenUnion.Internal.IfNotFound t r r) =&gt;
                 Member t r
          -- Defined in ‘Data.OpenUnion.Internal’
      This makes type inference for inner bindings fragile;
        either use MonoLocalBinds, or simplify it using the instance
    • In the type signature:
        payTo :: (Member RunContract effs) =&gt;
                 PaymentPubKeyHash -&gt; Integer -&gt; Eff effs ()
      In the expression:
        do contract1 &lt;- activateContractWallet (knownWallet 1) payContract
           let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
               payTo ::
                 (Member RunContract effs) =&gt;
                 PaymentPubKeyHash -&gt; Integer -&gt; Eff effs ()
               ....
           payTo pkh2 payment1
           void $ Emulator.waitNSlots 1
           ....
      In an equation for ‘payTrace’:
          payTrace payment1 payment2
            = do contract1 &lt;- activateContractWallet
                                (knownWallet 1) payContract
                 let pkh2 = ...
                     ....
                 payTo pkh2 payment1
                 ....
   |
46 |         payTo :: (Member RunContract effs) =&gt; PaymentPubKeyHash -&gt; Integer -&gt; Eff effs ()
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ok, 8 modules loaded.

</code></pre>
<p>Thanks!</p>

<plutus-pioneer-program><haskell><monad>
How to define the return type of `callEndPoint` appropriately?
# How to define the return type of `callEndPoint` appropriately?

(Asked by: username_0 on 2022-02-12)

In homework of week4, I refactored my solution:
payTrace :: Integer -> Integer -> EmulatorTrace ()
payTrace payment1 payment2 =  do
contract1 <- activateContractWallet (knownWallet 1) payContract
let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
callEndpoint @"pay" contract1 $ PayParams
   {
       ppRecipient = pkh2
   ,   ppLovelace = payment1
   }
void $ Emulator.waitNSlots 1
callEndpoint @"pay" contract1 $ PayParams
   {
       ppRecipient = pkh2
   ,   ppLovelace = payment2
   }
void $ Emulator.waitNSlots 1

to:
payTrace :: Integer -> Integer -> EmulatorTrace ()
payTrace payment1 payment2 =  do
contract1 <- activateContractWallet (knownWallet 1) payContract
let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
    payTo :: (Member RunContract effs) => PaymentPubKeyHash -> Integer -> Eff effs ()
    payTo pkh amount = callEndpoint @"pay" contract1 $ PayParams
       {
           ppRecipient = pkh
       ,   ppLovelace = amount
       }
payTo pkh2 payment1
void $ Emulator.waitNSlots 1
payTo pkh2 payment2
void $ Emulator.waitNSlots 1

(https://gitlab.com/moment-4/courses/plutus-pioneer/plutus-pioneer-program/-/blob/week04/code/week04/src/Week04/Homework.hs)
However, there are still 2 things I don't like about my current solution:

I'd prefer to put the payTo function in the where clause, but that doesn't seem to work properly (although I think I'm close thanks to Luis (https://discord.com/channels/826816523368005654/834340082273878046/942064349831381042). How would one define it in the where clause? (The solution of Luis put me on the right track, but I still can't get it right)

I still get compiler warnings about the type. How to define the type of the function properly, so I can get rid of the warnings as well?


src/Week04/Homework.hs:46:18: warning: [-Wsimplifiable-class-constraints]
    • The constraint ‘Member RunContract effs’ matches
        instance (Data.OpenUnion.Internal.FindElem t r,
                  Data.OpenUnion.Internal.IfNotFound t r r) =>
                 Member t r
          -- Defined in ‘Data.OpenUnion.Internal’
      This makes type inference for inner bindings fragile;
        either use MonoLocalBinds, or simplify it using the instance
    • In the type signature:
        payTo :: (Member RunContract effs) =>
                 PaymentPubKeyHash -> Integer -> Eff effs ()
      In the expression:
        do contract1 <- activateContractWallet (knownWallet 1) payContract
           let pkh2 = mockWalletPaymentPubKeyHash $ knownWallet 2
               payTo ::
                 (Member RunContract effs) =>
                 PaymentPubKeyHash -> Integer -> Eff effs ()
               ....
           payTo pkh2 payment1
           void $ Emulator.waitNSlots 1
           ....
      In an equation for ‘payTrace’:
          payTrace payment1 payment2
            = do contract1 <- activateContractWallet
                                (knownWallet 1) payContract
                 let pkh2 = ...
                     ....
                 payTo pkh2 payment1
                 ....
   |
46 |         payTo :: (Member RunContract effs) => PaymentPubKeyHash -> Integer -> Eff effs ()
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ok, 8 modules loaded.


Thanks!

**Tags:** plutus-pioneer-program, haskell, monad

---

## 1 answers

### Answer by username_1 on 2022-02-12. Score: 1 | Accepted answer

I don't know if this is what you expect but there are three ways to get rid of warnings:

1. add `{-# LANGUAGE MonoLocalBinds #-}`, like the warning hints
2. don't give a type for `payTo` and let Haskell infer it
3. if things worked before, the body of `payTo` was fine in the `EmulatorTrace` monad, so you could go for `payTo :: PaymentPubKeyHash -> Integer -> EmulatorTrace ()`

I'm not particularly fond of the idea of moving the function in a `where` clause if it depends on something you obtain in the body of the bigger function. You could consider adding another parameter and passing `contract1` as an argument, and then you can move it to `where`.

> **Comments:**
> **username_0**: Allright, thanks. Well, I just wanted to get rid of the warning and understand why it's there. So, seeing your solutions: 1. what does it mean (`MonoLocalBinds`)? 2. I try to understand the types passed everywhere. Is there no way I can give the right type signature? 3. The body was fine, but moving it to the where, makes in different (it's a different type in the do-bindings vs in the were clause. That being said, it makes more sense to keep in the `let`-binding? (Just trying to figure out the Haskell type system and monads and do-bindings)  
> **username_1**: 1. a Haskell extension meant to infer less polymorphic types. Details here: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/let_generalisation.html. 2. I'd say using `EmulatorTrace ()` for the result is the right type signature. The type you use is more general: `(Member RunContract effs) => ... -> Eff effs ()` can be specialized to `Eff '[StartContract, RunContract, Assert, Waiting, EmulatorControl, EmulatedWalletAPI, LogMsg String, Error EmulatorRuntimeError] ()`, which is `EmulatorTrace ()`, because RunContract is in the list of effects for EmulatorTrace thus the condition holds.  
> **username_1**: And 3, you use `contract1` in the body of `payTo` and if you move `payTo` to the `where` clause, `contract1` is no longer in scope, as it is local to the body of `payTrace`. Either leave `payTo` in the `let`-binding or make `payTo :: ContractHandle w s e -> PaymentPubKeyHash -> Integer -> EmulatorTrace ()`, move it to `where` and add `contract1` to the calls of `payTo` in the body of `payTrace`.  

---

