# Lifting const

*Originally posted on dev.to/gillchristian*.

Yesterday I shared this gist:

https://twitter.com/gillchristian/status/1175878924926095360

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

https://twitter.com/gillchristian/status/1176126201234169860

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`

.

```
class Functor f => Applicative f where
-- ...
-- | Sequence actions, discarding the value of the second argument.
(<*) :: f a -> f b -> f a
(<*) = liftA2 const
```

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.*