-
Notifications
You must be signed in to change notification settings - Fork 4
⚙️ Plutus Tutorial: Haskell Language Extensions for Smart Contracts
- 💎 Introduction
- 🧩 What Are Haskell Language Extensions?
- 🧠 Why Plutus Needs Them
- 🌐 Plutus Extensions Map (Visual Overview)
- ⚒️ Core On-Chain Extensions
- 🔧 Deriving and Serialization Extensions
- 🧮 Type-Level and Typed-Script Extensions
- 🧩 Syntax and Functional Control Extensions
- 🪄 Off-Chain and Emulator Extensions
- 🧾 Glossary of Key Extensions
- 🧭 Conclusion
Plutus, the smart contract language for Cardano, is built entirely in Haskell, but with restrictions and extensions that tailor it for blockchain execution.
Writing Plutus code means writing two worlds of Haskell:
- 🟦 On-chain — compiled to Plutus Core, run by Cardano nodes.
- 🟩 Off-chain — runs on users’ machines/wallets.
Because these environments differ, Plutus uses a special set of Haskell language extensions to safely compile, serialize, and manage contracts.
Language extensions modify the compiler’s behavior to unlock features not included in standard Haskell 2010.
Declared at the top of your file:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}Each extension enables additional syntax, typing rules, or compile-time features — crucial for converting your high-level code into Plutus Core bytecode.
| Purpose | Why It’s Needed |
|---|---|
| 🧱 Compile-time generation | Converts Haskell into Plutus Core using PlutusTx.compile. |
| ⚙️ Type-level programming | Safely enforce Datum, Redeemer, and ScriptContext types. |
| 🧮 Serialization | Automatically derive IsData, FromJSON, etc. |
| 🚫 Safety | Removes unsafe or non-deterministic Haskell features. |
| 🧭 Clarity | Reduces ambiguity between on-chain and off-chain code. |
Below is a color-coded classification of extensions used in Plutus development.
| Layer | Color | Description |
|---|---|---|
| 🟦 On-chain | 🔵 | Used for validators, minting policies, and scripts compiled to Plutus Core. |
| 🟩 Off-chain | 🟢 | Used for contract endpoints, wallet logic, and emulators. |
| 🟣 Shared | 🟣 | Used in both environments. |
┌────────────────────────────┐
│ Shared 🟣 │
│ DeriveAnyClass │
│ DeriveGeneric │
│ TypeApplications │
│ ScopedTypeVariables │
└────────────┬────────────────┘
│
┌─────────────────────────────────┼─────────────────────────────────┐
│ │ │
┌───────────────┐ ┌──────────────────┐ ┌────────────────┐
│ On-Chain 🔵 │ │ Off-Chain 🟢 │ │ Serialization 🟣│
│ TemplateHaskell│ │ OverloadedLabels │ │ IsData, ToJSON │
│ NoImplicitPrelude│ │ OverloadedStrings│ │ DeriveGeneric │
│ DataKinds │ │ NamedFieldPuns │ │ DeriveAnyClass │
│ GADTs, TypeOps │ │ FlexibleInstances│ │ TypeFamilies │
│ TypeFamilies │ │ QuasiQuotes │ │ DerivingStrategies │
└─────────────────┘ └──────────────────┘ └────────────────┘
🧩 Interpretation:
- Blue: On-chain extensions necessary for deterministic blockchain execution.
- Green: Off-chain Haskell features to handle wallet, emulator, and API interactions.
- Purple: Shared features — safe to use in both layers.
These extensions are fundamental for writing validators and minting policies.
| Extension | 🧰 Purpose | 💡 Example | ||||
|---|---|---|---|---|---|---|
TemplateHaskell |
Compiles Haskell to Plutus Core. | `$$(PlutusTx.compile [ | mkValidator | ])` | ||
NoImplicitPrelude |
Replaces standard Prelude with PlutusTx.Prelude. |
import PlutusTx.Prelude |
||||
DataKinds |
Promotes data constructors to the type level. | type Example = 'True |
||||
ScopedTypeVariables |
Keeps type variables in scope. | foo :: forall a. a -> a |
||||
BangPatterns |
Enables strict evaluation. | f !x = x + 1 |
🟦 Used in: On-chain scripts, validators, minting policies.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ScopedTypeVariables #-}
import qualified PlutusTx
import qualified PlutusTx.Prelude as PThese help Plutus automatically derive serialization logic for datums and redeemers.
| Extension | 🧰 Purpose | 💡 Example |
|---|---|---|
DeriveAnyClass |
Derive IsData for blockchain serialization. |
deriving (PlutusTx.IsData) |
DeriveGeneric |
Provides Generic for auto-derived instances. |
deriving (Generic) |
DerivingStrategies |
Controls deriving style. | deriving stock (Eq) |
GeneralizedNewtypeDeriving |
Inherit behaviors in newtypes. | newtype MyDatum = MyDatum Int deriving newtype (Eq) |
StandaloneDeriving |
Allows separate deriving declarations. |
deriving instance Eq MyDatum |
🟣 Used in: Both on-chain (serialization) and off-chain (Aeson JSON).
Critical for type-safe scripts and custom validator types.
| Extension | 🧠 Purpose | 💡 Example |
|---|---|---|
TypeApplications |
Specify type parameters explicitly. | foo @Integer 10 |
TypeFamilies |
Associate types with classes. | type family DatumType s |
TypeOperators |
Custom infix type constructors. | a :-> b |
GADTs |
Used in typed Plutus scripts. | data MyType a where ... |
KindSignatures |
Annotate kinds for clarity. | data MyData (a :: Type) |
🟦 Used in: Typed validators (Typed.Scripts.V2), state machines.
These enhance expressiveness and clarity in contracts.
| Extension | 🧰 Purpose | 💡 Example | |
|---|---|---|---|
LambdaCase |
Concise pattern-matching lambdas. | foo = \case Just x -> x; Nothing -> 0 |
|
OverloadedStrings |
String literals as BuiltinByteString. |
P.trace "debug" |
|
MultiParamTypeClasses |
Classes with multiple type params. | `class Convertible a b | a -> b` |
FunctionalDependencies |
Guides inference with above. | ` | a -> b` |
RecordWildCards |
Extract record fields easily. | TxInfo{..} |
|
NamedFieldPuns |
Simplify field naming. | TxInfo{txInputs} |
🟣 Used in: Both layers for code clarity and developer ergonomics.
Used for wallet logic, endpoints, and emulator testing.
| Extension | 🧰 Purpose | 💡 Example | ||
|---|---|---|---|---|
OverloadedLabels |
Endpoint syntax like @"deposit". |
callEndpoint @"lock" h1 param |
||
FlexibleInstances |
Flexible instance definitions. | instance FromJSON MyDatum |
||
DuplicateRecordFields |
Same record field names in different types. | data Wallet = Wallet {id :: Int} |
||
QuasiQuotes |
Embed mini DSLs. | `[quasi | ... | ]` |
NumericUnderscores |
Improves number readability. | 1_000_000 |
🟩 Used in: Plutus.Contract, Plutus.Trace.Emulator, Ledger.Value.
| Extension | Description |
|---|---|
| TemplateHaskell | Enables compile-time metaprogramming (PlutusTx.compile). |
| NoImplicitPrelude | Uses deterministic PlutusTx Prelude instead of Haskell’s. |
| DataKinds | Promotes constructors to type level. |
| DeriveAnyClass / DeriveGeneric | Auto-generate serialization logic. |
| TypeApplications | Apply types directly at call sites. |
| OverloadedStrings | Interprets "hello" as BuiltinByteString. |
| OverloadedLabels | Used in Contract endpoints. |
| GADTs / TypeFamilies | Advanced type safety for validator logic. |
✅ Plutus relies heavily on Haskell extensions to safely bridge high-level code and blockchain-level execution. ✅ On-chain code must stay deterministic and minimal — it uses extensions like:
TemplateHaskell
NoImplicitPrelude
DataKinds
TypeApplications
✅ Off-chain code can be flexible, using:
OverloadedLabels
DeriveGeneric
FlexibleInstances
✅ Shared extensions (DeriveAnyClass, ScopedTypeVariables, etc.) work seamlessly across both environments.
Bernard Sibanda is a global Technology Entrepreneur, Web3 and Software Consultant with a deep focus on Cardano Blockchain, Midnight and Community building.
Key Positions:
- Founder, CTO, Developer Advocate cohort #1, Fullstake Developer, Cardano Ambassador, Catalyst Project Manager, DREP-WIMS:
- Co-founder of ABL Tech and Cardano Africa Live
- EBU-certified Plutus Pioneer (Plutus/Haskell)
- Cohort #1 Plutus Pioneer Developer
- Catalyst Community Reviewer & Funded Projects Manager
-
DRep for WIMS-Cardano (ID:
drep1yguj8zu48n99pv70yl6ckzt9hdgjy8yjnlqs2uyzcpafnjgu4vkul) - Intersect Developer Advocate
- Intersect Committe Member 2025-2026
- Cardano Marketer,Promoter and blogger
- Cardano Open Source Contributor
- Cardano communities and events organizer and builder
- Cardano Ambassador for South Africa
Official links:
- Stablecoins Dex
- Coxygen Global Universities
- WIMS Cardano Global
- Cardano Africa Live
- WIMS Cardano Videos
- Cardano Smart Contract Videos
- Fullstack IT Consulting
Social links: