DAML Fundamentals: Optional Data Type

Reading Time: 3 minutes

DAML is a powerful open sourced language created to write distributed applications quickly, concisely and correctly. On this site, we have got blogs for you that help you in getting started with DAML. Just type DAML is the search box and hit enter 😉

DAML provides different data types to build the ledgers. You can get a quick overview of some of these types by reading about supported data types. In this blog we will explore the Optional data type provided by DAML. It is advisable to try along.

Optional Data Type

The Optional data type signifies the presence or the absence of a value.
Optional t has two representations namely Some t which represents the presence of the value of type t and None which represents the absence of the value. To use Optional we need to use import DA.Optional in our module.

Lets take an example here. Suppose we want to have a function that takes in an integer and returns the same integer only if the number is even. In such a case, what do if the number is odd? Optional values come to the rescue in such use cases where otherwise we would have to choose a default value which many times leads to confusion.

module LearnOptional where

import DA.Optional

isEven: Int -> Optional Int
isEven num = if (num % 2 == 0) then Some num else None

is_even_scenario = scenario do
     assert (isEven 5 == None)
     assert (isEven 4 == Some 4)

There are other useful functions provided for Optional by DAML and we will explore some of them in the next section.

Optional Functions

isSome

Returns true if the value of the optional is present else returns false. The following example shows a trivial usage of isSome.

explore_is_some: Optional Int -> Text
explore_is_some optInt =
    if (isSome optInt) then "Optional is present" else "Optional is absent"

is_some_scenario = scenario do
    assert(explore_is_some (Some 10) == "Optional is present")
    assert(explore_is_some None == "Optional is absent")

isNone

This is opposite to isSome. Returns true if the optional is absent else returns false.

explore_is_none: Optional Int -> Text
explore_is_none optInt =
    if (isNone optInt) then "Optional is absent" else "Optional is present"

is_none_scenario = scenario do
    assert(explore_is_none (Some 10) == "Optional is present")
    assert(explore_is_none None == "Optional is absent")

fromSome

fromSome extracts the value of the Optional when it is of type Some. It will throw an error if the Optional is of type None. If someone is familiar with Scala, this is similar to .get on Options in Scala.

optional_test = scenario do  
    let
        optInt = Some 5
        optText = Some "Hello"
    
    assert(fromSome optInt == 5)
    assert(fromSome optText == "Hello")

catOptionals

catOptionals works on a list of Optionals. Its input is a list of Optionals. And the output is the extracted values of the Optionals. If there are None types in the list, then those are discarded from the output. In the following example we input a list of integers to catOptionals and the list has None elements too. The output is a list of Integers without any value for None.

explore_cat_optionals = scenario do
    let optionals = [Some 1, None, Some 2, None, Some 3, None]
    let onlySomes = catOptionals optionals 
    assert(onlySomes == [1, 2, 3])

mapOptional

mapOptional helps to filter out values based on a certain transformer. It takes two inputs, a transformer and a list. The transformer applies to all the values of the list and then internally uses catOptionals to filter out the None values that may have resulted due to the transformer application.

isEven: Int -> Optional Int
isEven num = if (num % 2 == 0) then Some num else None

explore_map_optional = scenario do
    let ints = [1,2,3,4,5,6]
    let onlyEven = mapOptional (\x -> isEven x) ints
    assert(onlyEven == [2,4,6])

fromOptional

fromOptional takes a default value of type T and an optional value of type T. If the Optional is empty (i.e, it is None) it returns the default value else it extracts the value from Some and returns it. This is can be considered similar to Scala .getOrElse on Options.

give_me_text: Optional Text -> Text
give_me_text optText = fromOptional "unknown" optText

from_optional_scenario = scenario do
      assert (give_me_text (Some "hello") == "hello")
      assert (give_me_text None == "unknown")

I hope this blog would have helped you in understanding Optional type. Do explore other blogs on our site.

References


Knoldus-blog-footer-image

Written by 

Sonu Mehrotra is a Software Developer with industry experience of 5+ years. He is a Clean Code practitioner and an Agile follower. Sonu has helped financial institutions develop trading systems that make trading activities easier and more accessible to customers.