# Haskell Plutus : Lift, UnsafeLift, and safeLift

## 📚 Haskell Plutus : `Lift`, `UnsafeLift`, and `safeLift`

### Table of Contents

1. 🔍 Introduction to Lifting
2. 🧱 `Lift` Typeclass: The Bridge from Haskell to Plutus Core
3. ⚠️ `UnsafeLift`: Risky but Flexible
4. 🛡️ `safeLift`: Your Safety Net
5. 🧪 Example: Custom Type Lifting
6. 🧠 Quiz Yourself
7. 📘 Glossary of Terms
8. 🧩 Summary and Best Practices

***

### 1. 🔍 Introduction to Lifting

In Plutus, *lifting* refers to the process of converting **Haskell values** into **Plutus Core constants** so they can be used inside on-chain scripts. This is crucial because:

* **Plutus Core** (on-chain) has a limited set of primitive types.
* **Haskell** (off-chain) has a much richer type system.

➡️ Lifting makes Haskell data available inside Plutus scripts.

***

### 2. 🧱 `Lift` Typeclass: The Bridge from Haskell to Plutus Core

The `Lift` typeclass in Plutus defines how a Haskell value is **converted (lifted)** into a Plutus Core term.

#### 📦 Module

```haskell
PlutusTx.Lift
```

#### 🧾 Class Definition

```haskell
class Lift a where
  lift :: a -> Q (TExp (CompiledCode a))
```

#### ✅ Usage

You derive `Lift` for your types so that they can be compiled into Plutus scripts:

```haskell
{-# LANGUAGE TemplateHaskell #-}

import PlutusTx.Lift

data Color = Red | Blue | Green
PlutusTx.makeLift ''Color
```

This allows `Color` to be used in on-chain logic.

***

### 3. ⚠️ `UnsafeLift`: Risky but Flexible

The `UnsafeLift` typeclass is a more permissive lifting mechanism introduced in newer Plutus versions.

#### 😬 Why “Unsafe”?

* It doesn’t guarantee that the lifted representation will **preserve semantics** safely.
* It’s **used internally** by `Lift` and `safeLift`, but shouldn’t be relied on directly unless you know what you're doing.

#### 🧾 Class

```haskell
class UnsafeLift a where
  makeUnsafeLift :: a -> CompiledCode a
```

💡 Usually, you don’t use this directly.

***

### 4. 🛡️ `safeLift`: Your Safety Net

The `safeLift` function uses the `UnsafeLift` instance but adds compile-time guarantees using Template Haskell.

#### ✅ Safer Interface

```haskell
safeLift :: UnsafeLift a => a -> Q (TExp (CompiledCode a))
```

This is the preferred way to lift Haskell values inside Template Haskell expressions.

#### 💡 Example

```haskell
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}

import PlutusTx
import PlutusTx.Lift (safeLift)
import GHC.Generics (Generic)

data Token = Token { symbol :: BuiltinByteString, name :: BuiltinByteString }
  deriving (Generic, ToData, FromData)

PlutusTx.makeLift ''Token

myLiftedToken :: Q (TExp (CompiledCode Token))
myLiftedToken = safeLift (Token "ADA" "Coin")
```

***

### 5. 🧪 Example: Custom Type Lifting

Let's walk through lifting a custom record type:

#### 🧾 Type Definition

```haskell
data User = User
  { userId :: Integer
  , username :: BuiltinByteString
  } deriving (Generic, ToData, FromData)
```

#### ✅ Derive Lift

```haskell
PlutusTx.makeLift ''User
```

#### 🚀 Lift a Value

```haskell
liftedUser :: Q (TExp (CompiledCode User))
liftedUser = safeLift (User 101 "cardanoFan")
```

This allows `User` to be safely passed into on-chain logic.

***

### 6. 🧠 Quiz Yourself

> ✅ Which of the following is the safest way to lift a value?
>
> A. `lift value` B. `makeUnsafeLift value` C. `safeLift value` D. `compile value`

**Answer**: ✅ **C. `safeLift value`**

***

### 7. 📘 Glossary of Terms

| Term                      | Meaning                                                           |
| ------------------------- | ----------------------------------------------------------------- |
| **Lift**                  | A typeclass allowing Haskell values to be embedded in Plutus Core |
| **PlutusTx**              | Module containing TH-based tools for Plutus                       |
| **Template Haskell (TH)** | Meta-programming in Haskell to generate code at compile-time      |
| **CompiledCode**          | A wrapper type representing compiled Plutus Core                  |
| **BuiltinByteString**     | Optimized byte strings for on-chain Plutus logic                  |
| **Q**                     | The Template Haskell monad used for generating code               |
| **TExp**                  | A typed Template Haskell expression                               |
| **UnsafeLift**            | An internal or low-level way to lift values without checks        |
| **safeLift**              | A safer way to lift using Template Haskell and `UnsafeLift`       |

***

### 8. 🧩 Summary and Best Practices

| ✅ Do                                                       | 🚫 Don’t                                                  |
| ---------------------------------------------------------- | --------------------------------------------------------- |
| Use `safeLift` for all Template Haskell-based lifting      | Use `UnsafeLift` unless you really know what you’re doing |
| Derive `Lift` with `makeLift` or `makeLiftData`            | Manually implement `Lift` unless needed                   |
| Keep lifted types small and serializable                   | Lift large Haskell types with complex dependencies        |
| Use `BuiltinByteString`, `Integer`, etc. for compatibility | Use `String`, `Int`, or complex types directly            |

***
