DAML seems to have a forA
corresponding to a mapA
. Just for the sake of completeness, why is there no for
corresponding to a map
?
This is primarily due to being based on Haskell. Haskell has a for
function but it is actually equivalent to forA
in DAML. So to avoid any potential confusion, we did not add a for
to DAML. That said, I don’t think it would be that unreasonable to add it.
Be aware that map
is specialised to list, and as such we generally prefer to use fmap
which is the same function generalised over all Functor
’s from which map
is derived. This contrasts with mapA
which is already generalised over Applicative
and Traversable
*.
Moreover when we use fmap
(over []
, Optional
, NonEmpty
, Update
, or some other Functor
), we generally use the operator version <$>
. So instead of writing fmap someFunction someList
we write somefunction <$> someFunctor
. This is generally easier to read, especially as operator precedence often allows us to eliminate multiple parentheses by using an operator like this**.
There are occasions where the code is easier to read if we swap the function and the list arguments — fortunately, while there is no for
function in the standard library, there is a for
operator <&>
. So you can always write someFunctor <&> someFunction
.
In short, you will almost always find your code easier to read and write if you use <$>
in preference to fmap
and occasionally <&>
where you want the arguments flipped.
- In fact in much the same way the existence of a lawful
fmap
is what defines aFunctor
, the existence of a lawfulmapA
is what defines aTraversable
.
** The two common exceptions to this are:
- Where you want to partially apply
fmap
to define a function. ie.
f : Update Text -> Update Int f = fmap length
- Where you need to fmap over nested functors, ie. applying
f : (a -> b)
toarg : [Optional a]
to get[Optional b]
. So we do find a few places in our code where we writefmap f <$> arg
.
A quick grep indicates 1805 uses of <$>
, 241 uses of <&>
, 267 uses of fmap
(the vast majority of which fall into case 1 above).
PS. As an aside, as you move from introductory to intermediate DAML, it is highly recommended that you take the time to explore and understand the core typeclasses Functor
, Applicative
, Action
, and Traversable
, their functions, operators, and hierarchy, as advanced DAML techniques often assume a familiarity with these concepts, and they do allow you to simplify otherwise quite complicated DAML code.