<p>The entire computation is in the <code>Contract</code> monad and we use the <code>do</code> notation. Thus when we write <code>utxos &lt;- utxosAt $ npAddress np</code>, the type of <code>utxos</code> is <code>Map TxOutRef ChainIndexTxOut</code>, so everything typechecks.</p>
<p>A simpler example:</p>
<pre><code>import Text.Read
plusOne :: String -&gt; Maybe Integer
plusOne s = do
 x &lt;- readMaybe s :: Maybe Integer
 return $ x + 1
</code></pre>
<p>The type of <code>readMaybe</code> is (here) <code>String -&gt; Maybe Integer</code>, but since we are after <code>do</code>, <code>x</code> is of type <code>Integer</code>, not <code>Maybe Integer</code>. So <code>plusOne &quot;3&quot;</code> is <code>Just 4</code>.</p>

CC BY-SA 4.0
2022-02-23T19:12:06.147Z
Thank you for taking the time to help me. I verified your response, read up on do notation and decided to try using this concept in my own project. I'm not getting the results I expected and edited my original post in hopes you could take a look for me.
Kyle Murphy
CC BY-SA 4.0
2022-02-23T19:57:03.550Z
The problem is that `getNFT :: Wallet -> Value` and Value is not a Monad, so you can't use the do notation there. Also,`utxosAt` is a computation in the `Contract` monad, so maybe you want to change to `getNFT :: Wallet -> Contract w s e Value`, where you might have concrete types for the variables w, s, e. Then you should also have `return v` on one case branch, and accordingly `return` on the other branch.
Mihai Codescu
CC BY-SA 4.0
2022-02-23T20:09:30.060Z
I'm not sure this is the right place, but I'll explain a bit more: if you write a function `f :: String -> Integer` you can't use `do` - it's just for instances of the `Monad` class. Also, you can't mix the monads: in a function `g :: a -> Maybe b` you can use `do` but you can't write `x <- h y` where `h :: y -> m x` and `m` is another monad than `Maybe` - note that I use `y` both for a type and a value of that type, to simplify matters.
Mihai Codescu
CC BY-SA 4.0
2022-02-25T15:03:26.553Z
through your advice I was able to fix my functions and gain a better understanding of how Monads work. Having my function `getNFT` return a `Contract` monad causes another problem for me because I need to pass the Value in `Contract w s e Value` into `mustPayToPubKey :: forall i o. PaymentPubKeyHash -> Value -> TxConstraints i o`
Kyle Murphy
CC BY-SA 4.0
2022-02-25T16:55:29.307Z
If you share your whole code with me, I'll try to help. I would guess you must replace a `let v = getNFT ...` with `v <- getNFT ...`, as `mint` is in the `Contract` monad already.
Mihai Codescu
CC BY-SA 4.0
2022-02-25T22:22:58.597Z
https://github.com/DappDeveloper1/Royalty/blob/main/Royalty.hs ---- you'll find that it currently doesn't compile because getNFT returns a Contract and the nft variable in SellParams expects a Value. If I change SellParams to expect a Contract Value, it creates another problem because Contract does not support Show, Generic, FromJSON, and ToJSON
Kyle Murphy
CC BY-SA 4.0
2022-02-26T05:03:29.447Z
You shouldn't have  a Contract in SellParams, it's not how it's done. And you also can't have `nft = getNFT ...` there because you expect a Value and get a Contract ... Value. You also can't say `ǹft <- getNFT ...` before the `callEndpoint` because you are in the EmulatorTrace monad and this computation is in the Contract monad. It seems to me you should make `getNFT`  a part of sell - this is where it conceptually belongs.
Mihai Codescu
CC BY-SA 4.0
2022-02-19T20:23:13.283Z
2022-02-19T20:23:13.283Z
Mihai Codescu
<p>I was reviewing the code from <a href="https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs" rel="nofollow noreferrer">https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs</a> and I don't understand why this section does not cause a compile error.</p>
<pre><code>utxos &lt;- utxosAt $ npAddress np
    case Map.keys utxos of
        []       -&gt; Contract.logError @String &quot;no utxo found&quot;
        oref : _ -&gt; do
</code></pre>
<pre><code>utxosAt :: forall w s e. AsContractError e =&gt; Address -&gt; Contract w s e (Map TxOutRef ChainIndexTxOut)
</code></pre>
<pre><code>keys :: Map k v -&gt; [k]
</code></pre>
<p>My expectation is that the variable utxos has type Contract w s e (Map TxOutRef ChainIndexTxOut). This should cause an error on <code>Map.keys utxos</code>, but it doesn't.</p>
<p>Edit:
My code:</p>
<pre><code>getNFT :: Wallet -&gt; Value
        getNFT w = do
            utxos &lt;- utxosAt $ mockWalletAddress w
            case getValue utxos of
                Just v -&gt; v
                Nothing -&gt; Ada.lovelaceValueOf 1000000
</code></pre>
<p>The type of getValue is <code>getValue :: Map.Map TxOutRef ChainIndexTxOut -&gt; Maybe Value</code></p>
<p>The errors I am getting are:</p>
<pre><code> error:
    • Couldn't match expected type ‘Value’
                  with actual type ‘Contract w0 s0 e0 b0’
    • In a stmt of a 'do' block: utxos &lt;- utxosAt $ mockWalletAddress w
      In the expression:
        do utxos &lt;- utxosAt $ mockWalletAddress w
           case getValue utxos of
             Just v -&gt; v
             Nothing -&gt; lovelaceValueOf 1000000
      In an equation for ‘getNFT’:
          getNFT w
            = do utxos &lt;- utxosAt $ mockWalletAddress w
                 case getValue utxos of
                   Just v -&gt; v
                   Nothing -&gt; lovelaceValueOf 1000000
    |
179 |             utxos &lt;- utxosAt $ mockWalletAddress w
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compilation Error, Line 181, Column 27 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: v
      In a case alternative: Just v -&gt; v
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -&gt; v
          Nothing -&gt; lovelaceValueOf 1000000
    |
181 |                 Just v -&gt; v
    |                           ^
Compilation Error, Line 182, Column 28 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: lovelaceValueOf 1000000
      In a case alternative: Nothing -&gt; lovelaceValueOf 1000000
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -&gt; v
          Nothing -&gt; lovelaceValueOf 1000000
    |
182 |                 Nothing -&gt; Ada.lovelaceValueOf 1000000
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
</code></pre>

<plutus-pioneer-program>
How to get the return type of a contract
# How to get the return type of a contract

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

I was reviewing the code from https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs and I don't understand why this section does not cause a compile error.
utxos <- utxosAt $ npAddress np
    case Map.keys utxos of
        []       -> Contract.logError @String "no utxo found"
        oref : _ -> do

utxosAt :: forall w s e. AsContractError e => Address -> Contract w s e (Map TxOutRef ChainIndexTxOut)

keys :: Map k v -> [k]

My expectation is that the variable utxos has type Contract w s e (Map TxOutRef ChainIndexTxOut). This should cause an error on Map.keys utxos, but it doesn't.
Edit:
My code:
getNFT :: Wallet -> Value
        getNFT w = do
            utxos <- utxosAt $ mockWalletAddress w
            case getValue utxos of
                Just v -> v
                Nothing -> Ada.lovelaceValueOf 1000000

The type of getValue is getValue :: Map.Map TxOutRef ChainIndexTxOut -> Maybe Value
The errors I am getting are:
 error:
    • Couldn't match expected type ‘Value’
                  with actual type ‘Contract w0 s0 e0 b0’
    • In a stmt of a 'do' block: utxos <- utxosAt $ mockWalletAddress w
      In the expression:
        do utxos <- utxosAt $ mockWalletAddress w
           case getValue utxos of
             Just v -> v
             Nothing -> lovelaceValueOf 1000000
      In an equation for ‘getNFT’:
          getNFT w
            = do utxos <- utxosAt $ mockWalletAddress w
                 case getValue utxos of
                   Just v -> v
                   Nothing -> lovelaceValueOf 1000000
    |
179 |             utxos <- utxosAt $ mockWalletAddress w
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compilation Error, Line 181, Column 27 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: v
      In a case alternative: Just v -> v
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -> v
          Nothing -> lovelaceValueOf 1000000
    |
181 |                 Just v -> v
    |                           ^
Compilation Error, Line 182, Column 28 (jump)
 error:
    • Couldn't match expected type ‘Contract w0 s0 e0 b0’
                  with actual type ‘Value’
    • In the expression: lovelaceValueOf 1000000
      In a case alternative: Nothing -> lovelaceValueOf 1000000
      In a stmt of a 'do' block:
        case getValue utxos of
          Just v -> v
          Nothing -> lovelaceValueOf 1000000
    |
182 |                 Nothing -> Ada.lovelaceValueOf 1000000
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^

**Tags:** plutus-pioneer-program

---

## 1 answers

### Answer by username_1 on 2022-02-19. Score: 0

The entire computation is in the Contract monad and we use the do notation. Thus when we write utxos <- utxosAt $ npAddress np, the type of utxos is Map TxOutRef ChainIndexTxOut, so everything typechecks.
A simpler example:
import Text.Read
plusOne :: String -> Maybe Integer
plusOne s = do
 x <- readMaybe s :: Maybe Integer
 return $ x + 1

The type of readMaybe is (here) String -> Maybe Integer, but since we are after do, x is of type Integer, not Maybe Integer. So plusOne "3" is Just 4.

> **Comments:**
> **username_0**: Thank you for taking the time to help me. I verified your response, read up on do notation and decided to try using this concept in my own project. I'm not getting the results I expected and edited my original post in hopes you could take a look for me.  
> **username_1**: The problem is that `getNFT :: Wallet -> Value` and Value is not a Monad, so you can't use the do notation there. Also,`utxosAt` is a computation in the `Contract` monad, so maybe you want to change to `getNFT :: Wallet -> Contract w s e Value`, where you might have concrete types for the variables w, s, e. Then you should also have `return v` on one case branch, and accordingly `return` on the other branch.  
> **username_1**: I'm not sure this is the right place, but I'll explain a bit more: if you write a function `f :: String -> Integer` you can't use `do` - it's just for instances of the `Monad` class. Also, you can't mix the monads: in a function `g :: a -> Maybe b` you can use `do` but you can't write `x <- h y` where `h :: y -> m x` and `m` is another monad than `Maybe` - note that I use `y` both for a type and a value of that type, to simplify matters.  
> **username_0**: through your advice I was able to fix my functions and gain a better understanding of how Monads work. Having my function `getNFT` return a `Contract` monad causes another problem for me because I need to pass the Value in `Contract w s e Value` into `mustPayToPubKey :: forall i o. PaymentPubKeyHash -> Value -> TxConstraints i o`  
> **username_1**: If you share your whole code with me, I'll try to help. I would guess you must replace a `let v = getNFT ...` with `v <- getNFT ...`, as `mint` is in the `Contract` monad already.  
> **username_0**: https://github.com/DappDeveloper1/Royalty/blob/main/Royalty.hs ---- you'll find that it currently doesn't compile because getNFT returns a Contract and the nft variable in SellParams expects a Value. If I change SellParams to expect a Contract Value, it creates another problem because Contract does not support Show, Generic, FromJSON, and ToJSON  
> **username_1**: You shouldn't have  a Contract in SellParams, it's not how it's done. And you also can't have `nft = getNFT ...` there because you expect a Value and get a Contract ... Value. You also can't say `ǹft <- getNFT ...` before the `callEndpoint` because you are in the EmulatorTrace monad and this computation is in the Contract monad. It seems to me you should make `getNFT`  a part of sell - this is where it conceptually belongs.  

---

