Skip to content
Discussions/App Development/forA vs mapForum ↗

forA vs map

App Development3 posts300 viewsLast activity Dec 2022
NE
Neelam_DwivediOP
Dec 2022

I am trying to come up with examples on how forA and map work similarly with just their arguments switched. The following code is an attempt at that:

encryptListUsingMap : [Text] -> [Text]
encryptListUsingMap x = map sha256  x

encryptListUsingForA: [Text] -> [Text]
encryptListUsingForA x = forA  x sha256

The map sha256 x works, but forA x sha256 doesn’t compile. The error message is

Couldn't match type ‘Text’ with ‘m b’
      Expected type: Text -> m b
        Actual type: Text -> Text
    • In the second argument of ‘forA’, namely ‘sha256’
      In the expression: forA x sha256

Does it have something to do with the way sha256 works?

Just to add to this, the following two statements work fine:

forA x (%) y
map (% y) x 
GA
Gary_Verhaegen
Dec 2022

Hi @Neelam_Dwivedi,

forA is not “map with its arguments switched”. If you want “map with its arguments switched”, you can use (flip map).

Let’s take a look at their types:

map : (a -> b) -> [a] -> [b]
forA : (Applicative m) => [a] -> (a -> m b) -> m [b]

As you can see, there’s this Applicative constraint in the way. You can think of forA as the equivalent of map but for actions.

Here’s a concrete example:

module Main where

import Daml.Script

pretend_script : Int -> Script Int
pretend_script x = return (x + 1)

setup : Script ()
setup = script do
  let a : [Script Int] = map pretend_script [1, 2, 3]
  let b : Script [Int] = forA [1, 2, 3] pretend_script
  -- c <- a -- this line fails
  d <- b -- this succeeds
  e <- sequence a -- also succeeds
  return ()

Notice the difference in types between a and b. Specifically, you can “unwrap” b with <- notation, but you can’t do the same for a (without using the sequence function).

For completeness:

sequence : (Applicative m) => [m a] -> m [a]
NE
Neelam_Dwivedi
Dec 2022

Thanks @Gary_Verhaegen

Yes, the documentation also compares forA with mapA, and not with map and so my guess was also that this has something to do with forA taking Applicative f, while map takes (a ->b). But I got thrown off when I saw that forA takes (%).

Thanks for a great explanation!

← Back to Discussions