Can you simplify this code?
let eOpt = case a.bOpt of
None -> None
Some b -> case b.cOpt of
None -> None
Some c -> case c.dOpt of
None -> None
Some d -> d.eOpt
I tried fmap
and friens, but it keeps the nested optional type.
1 Like
You can do this using monadic binds
let eOpt =
a.bOpt >>= \b ->
b.cOpt >>= \c ->
c.dOpt >>= \d ->
d.eOpt
Of course do notation looks a bit nicer here:
let eOpt = do
b <- a.bOpt
c <- b.cOpt
d <- c.dOpt
d.eOpt
4 Likes
Is this a case where (Kleisli) composition of the arrows with >=>
(from DA.Action
) might make things a bit cleaner, or is it considered that this degrades readability?
let eOpt = (.bOpt) >=> (.cOpt) >=> (.dOpt) >=> (.eOpt) $ a
1 Like
That will highly depend on the audience for the code, so “check with your team”, I suppose.
Personally, if we’re going down that path, I’d prefer for the entire line to read “from left to right”, something like:
module Main where
import Daml.Script
data A = A with b : Optional B
data B = B with c : Optional C
data C = C with d : Optional D
data D = D with e : Optional E
data E = E Int
(|>) : a -> (a -> b) -> b
infix 0 |>
(|>) arg f = f arg
(>=>) : Action m => (a -> m b) -> (b -> m c) -> (a -> m c)
(f >=> g) x = f x >>= g
setup : Script ()
setup = script do
let a = A None
let e = a |> (.b) >=> (.c) >=> (.d) >=> (.e)
return ()
1 Like