# If-then-else without else

**URL:** <https://forum.canton.network/t/if-then-else-without-else/6706>\
**Category:** App Development\
**Created:** [June 21, 2023, 8:34pm UTC](https://forum.canton.network/t/if-then-else-without-else/6706 "2023-06-21T20:34:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oleg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/oleg/32/5639_2.png) [@Oleg](https://forum.canton.network/u/Oleg)\
**Post date:** [June 21, 2023, 8:34pm UTC](https://forum.canton.network/t/if-then-else-without-else/6706/1 "2023-06-21T20:34:26Z")

</div>

Hi! I wrote a code like this:  
…

```haskell
nonconsuming choice SomeChoice : ContractId SomeContract
      with
        someField1 : Common.Id
        someField2 : Decimal
        someField3 : Party
      controller someController
      do
        assertMsg "Some error text" $ someCondition
        template1Cid <- functionOnTemplate1Cid temp1Cid party1 party2
 
        if someCondition2 then do
          (template1Cid, _) <- exercise template1Cid SomeChoiceOnThatTemplate with someParam = someValue

        template123Cid <- exercise template1Cid SomeChoice2OnThatTemplate with someParam2 = someValue2
        archive self
        create ThirdTemplate with ..

```

I only doubting about if-then statement without else part. Is it legal to write so if I just aiming to include 1 conditional action? Any meaningful pointers to the Daml reference are highly appreciated!

---

<div class="post-metadata">

**Author:** ![Ben\_M](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/ben_m/32/3080_2.png) [@Ben\_M](https://forum.canton.network/u/Ben_M)\
**Post date:** [June 22, 2023, 3:29am UTC](https://forum.canton.network/t/if-then-else-without-else/6706/2 "2023-06-22T03:29:47Z")

</div>

Hi Oleg,

You should use `If ... Else` the same as many other programming languages.

Please refer to the [If-then-Else](https://docs.daml.com/daml/reference/expressions.html#if-then-else) documentation for some straightforward examples, and also read the Functional Programming 101 [If…Else](https://docs.daml.com/daml/intro/10_Functional101.html#if-else) control flow examples.

Regards, Ben.

---

<div class="post-metadata">

**Author:** ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)\
**Post date:** [June 22, 2023, 9:10am UTC](https://forum.canton.network/t/if-then-else-without-else/6706/3 "2023-06-22T09:10:55Z")

</div>

Hi @Oleg,

Daml is a purely functional language, which among other things means that every code construct is an expression, and every expression returns a value. It’s also a statically typed language, meaning every expression must have a (statically defined) type.

So the `if condition then then-expression else else-expression` construct is an expression that returns a value of a given type. From a type perspective:

- The `condition` expression needs to evaluate to a Boolean value.
- The `then-expression` and the `else-expression` must have the same type, which will also be the type of the overall `if` expression.

So in `a = if ... then ... else ...`, `a` can have a single, defined type.

The language does not support an `if` expression without an `else` branch. Given the above constraints, how could it? If you write

```haskell
a = if False then 4

```

what is the type of `a`? What is the value of `a`? That would just not make sense.

Now, in the specific context of a `do` block, it’s tempting to think of `if` as a statement rather than an expression. But the language does not make a special case here; it’s the same `if` construct and it’s just as much of an expression. Within a `do` block, a line of the form

```haskell
if ... then ... else ...

```

is a shorthand for

```haskell
_unused_name <- if ... then ... else ...

```

which is to say we are still expecting a resulting value and we are still capturing it in a local binding, even though that binding is not getting used later on. Thus we still need an `else` branch to get a meaningful, well-typed expression.

If you’re not meaning to use the result of your `then` branch, you can rewrite your code to

```haskell
        if someCondition2 then do
          exercise template1Cid SomeChoiceOnThatTemplate with someParam = someValue
          pure ()
        else
          pure ()

```

such that both branches return an `Action ()`.

---

<div class="post-metadata">

**Author:** ![Oleg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/oleg/32/5639_2.png) [@Oleg](https://forum.canton.network/u/Oleg)\
**Post date:** [June 22, 2023, 12:36pm UTC](https://forum.canton.network/t/if-then-else-without-else/6706/4 "2023-06-22T12:36:12Z")

</div>

Hi @Gary_Verhaegen ,  
Thanks for your reply.  
Let me try answer this one:  
_If you write_

```haskell
a = if False then 4

```

_what is the type of `a`? What is the value of `a`? That would just not make sense._

The type might be Optional Int and value None, Well, with a small adjustment “Some 4” instead of just 4. And assuming If could infer the type of missed else part to be the same as for then one. Which I believe not a big deal for Daml. It guesses sometimes much less obvious things.  
But here comes the reason why I cleaned up my code to paste it here, for you guys to find out the specific usage context of a do block, NOT the variable value assignment.  
Transferring your example closer to mine, type of my incomplete if…else might be Optional Action() or so.  
However your answer inspired me to check the reference for Action () type (hope it’s type and I’m not mixing up things) description, and I surprisingly found even more elegant solution - [when function](https://docs.daml.com/daml/stdlib/DA-Action.html#function-da-action-when-35467):

> when final (archive contractId)

I used it in my code and … no squiggles!

```haskell
when someCondition2 ((template1Cid, _) <- exercise template1Cid SomeChoiceOnThatTemplate with someParam = someValue)

```

Looks nice and concise. If it really works as I expected then I guess it’s a perfect solution.

If I’m wrong, please let me know.

Few more reasons why I asked it here:  
-no errors were given by Daml extension (VS Code) to my code, well at least no squiggles (didn’t try to build yet)  
-no clear syntax reference which will give an idea of what is required and what is optional part of construction. Only examples.  
-similar stackoverflow Haskell (which as I know the nearest relative for Daml) [discussion](https://stackoverflow.com/questions/50473205/how-do-i-use-if-then-else-statement-with-no-else-condition-in-haskell). No clear (at least for me) answer there.

---

<div class="post-metadata">

**Author:** ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)\
**Post date:** [June 22, 2023, 12:49pm UTC](https://forum.canton.network/t/if-then-else-without-else/6706/5 "2023-06-22T12:49:07Z")

</div>

> [@Oleg](#):
>
> The type might be Optional Int and value None, Well, with a small adjustment “Some 4” instead of just 4. And assuming If could infer the type of missed else part to be the same as for then one. Which I believe not a big deal for Daml. It guesses sometimes much less obvious things.

So then the issue you’d get here is that your `if` appears in a position where Daml requires an `Action _` type, and if it gets an `Optional (Action _)` it won’t be able to proceed. You’d need to unwrap the `Optional` first. We could, in general, say that if an `if` expression doesn’t have an `else`, we implicitly wrap it into an `Optional`, but then in your case you’d have to write something like:

```haskell
nonconsuming choice SomeChoice : ContractId SomeContract
      with
        someField1 : Common.Id
        someField2 : Decimal
        someField3 : Party
      controller someController
      do
        assertMsg "Some error text" $ someCondition
        template1Cid <- functionOnTemplate1Cid temp1Cid party1 party2
 
        let opt = if someCondition2 then do
          (template1Cid, _) <- exercise template1Cid SomeChoiceOnThatTemplate with someParam = someValue
        case opt of
          Nothing -> pure ()
          Some action -> action

        template123Cid <- exercise template1Cid SomeChoice2OnThatTemplate with someParam2 = someValue2
        archive self
        create ThirdTemplate with ..

```

and I don’t think you’d gain much there.

Using `when` is a good option here, but I feel compelled to point out that `when` is not magic, is not special, and is not a built-in (unlike `if`). Specifically, it is defined [here](https://github.com/digital-asset/daml/blob/35f4566222a7305b000d5f6e1c0d239d3bb0c985/compiler/damlc/daml-stdlib-src/DA/Action.daml#L17-L28) as:

```haskell
when : Applicative f => Bool -> f () -> f ()
when p s = if p then s else pure ()

```
