In Scala you the concept of partial functions. These are useful for instance in collect
function on collections, e.g.:
1 to 10 collect {
case x if x % 2 == 0 => x.toString
}
While it is recommended to avoid partial functions, under some circumstances they might be useful. I was wondering if this would be (or is?) possible in DAML? Something like the pseudo code:
collect [1..10] (case x | x % 2 == 0 -> show x) -- ["2", "4", "6", "8", "10"]
1 Like
There is no builtin concept of partial functions like there is in Scala. Functions with incomplete pattern matches or calls to error
are called partial functions but contrary to Scala you cannot handle the error case so they behave quite differently.
If you want something similar to a partial function in Scala, change the return type of your function to Optional a
. You can then use mapOptional
as the equivalent of collect
. Putting things together, your example can be rewritten as follows:
evenToText : Int -> Optional Text
evenToText x
| x % 2 == 0 = Some (show x)
| otherwise = None
evenTexts : [Text]
evenTexts = mapOptional evenToText [1..10]
1 Like
Thanks, that seems like a viable option.
Will using Optional
cause heap allocations at runtime? Or are these actually modelled as value types?
1 Like
It does involve a heap allocation atm but I would be surprised if that becomes the bottleneck atm. In general, there are a ton of heap allocations in the interpreter atm and trying to optimize allocations in your DAML code is mostly not a useful optimization at this point.
1 Like
Thanks, I was just curious whether we are closer the JVM than to Haskell in this particular case. (I assume the Maybe
is a value type in Haskell.)
1 Like
In Haskell Just
also has a pointer to the value rather than the value itself. You can unpack fields in Haskell but only if they are not polymorphic.
1 Like
Another option here would be to use list comprehension notation:
module Main where
setup = scenario do
let evensAsText = [show x | x <- [1..10], x % 2 == 0]
debug evensAsText
2 Likes