forA vs map

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 

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]

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!