Yesterday I shared this gist:

#100DaysOfFP Day 23

One thing I find interesting about Haskell, and FP in general, the simple patterns keep repeating as more complexity is added.

The sequence operators from Applicative and Monad are the "lifted" versions of `const`.21:05 PM - 22 Sep 2019

And I planned to expand on it today based on some assumptions I had.

@RiccardoOdone I saw it in haskellbook.com 😏

If you liftA2 const the signature is the same but I doesn't behave as (<*) and (>>) though, I'll point that out today.13:28 PM - 23 Sep 2019

By playing around in GHCi I found out that my assumption was wrong.

So I did a bit of digging, by digging I mean Hoogling the functions and checking their sources in Hackage, to understand why.

I found some interesting things.

Let's check again how the operator `(<*)`

works.

```
(<*) :: Applicative f => f a -> f b -> f a
```

As it is always the case in Haskell, the signature says a lot. It looks like it takes two applicatives and returns the first one.

```
Just 1 <* Just 2 -- Just 1
```

And yes, that's right. But there's more...

It does not only return the first one discarting the second. Instead it "runs" both and returns the first one. How do we know it "runs" both? Because the semantic of such applicative (in this case Maybe) are *respected*:

```
Nothing <* Just 1 -- Nothing
Just 1 <* Nothing -- Nothing
```

And that is the difference with `const`

.

```
Just 1 `const` Just 2 -- Just 1
Just 1 `const` Nothing -- Just 1
Nothing `const` Just 1 -- Nothing
```

When I said that `(<*)`

is the "lifted" version of `const`

I didn't mean *lifted* in the Haskell sence, I meant *lifted* as in the function was used in the context of an applicative. Well I guess that's kind of what *lifted* means, so let's try again. What I meant is that the signature was "the same" but in the applicative context (same semantics, always returning the first argument and discarting the second).

Turns out, `(<*)`

is actually the "lifted" version of `const`

(in the Haskell sense). Oh, and that's exactly the implementation in `base`

.

So what I was wrong about? 🤔

I assumed that if you *lifted* `const`

it would still behave as the good ol' const.

```
constA = liftA2 const
Just 1 `constA` Just 2 -- Just 1
Just 1 `constA` Nothing -- Just 1
Nothing `constA` Just 1 -- Nothing
```

Well, as we saw already, it doesn't. As I said it *respects* the semantics of the applicative.

```
constA = liftA2 const
Just 1 `constA` Just 2 -- Just 1
Just 1 `constA` Nothing -- Nothing
Nothing `constA` Just 1 -- Nothing
```

Because that is the whole point of `liftA2`

.

* to be continued (whit a deeper look into `liftA2`

).

*P.S. Yeah I used a "lifting" 🏋️ picture in a post about lifting. Sorry.*

## Discussion (1)

The series is awesome! Keep it up!