Skip to content

Haskell & Plutus Language Extensions

Bernard Sibanda edited this page May 20, 2025 · 6 revisions

Haskell & Plutus Language Extensions

Table of Contents

Extensions

1. GADTs

Category: Type System
Scope: Haskell
How to Enable: {-# LANGUAGE GADTs #-}

When to Use:
When you need more precise typing in data constructors (e.g., embedded DSLs).

Usage Example:

data Expr a where
  Lit :: Int -> Expr Int
  Add :: Expr Int -> Expr Int -> Expr Int

2. TypeFamilies

Category: Type System
Scope: Haskell
How to Enable: {-# LANGUAGE TypeFamilies #-}

When to Use:
When you need type-level functions associated with type classes.

Usage Example:

type family F a :: *
type instance F Int = Bool

3. MultiParamTypeClasses

Category: Type Classes
Scope: Haskell
How to Enable: {-# LANGUAGE MultiParamTypeClasses #-}

When to Use:
When a type class logically relates more than one type.

Usage Example:

class Convertible a b where
  convert :: a -> b

4. FunctionalDependencies

Category: Type Classes
Scope: Haskell
How to Enable: {-# LANGUAGE FunctionalDependencies #-}

When to Use:
To help GHC infer types in multi-parameter type classes.

Usage Example:

class Convertible a b | a -> b where
  convert :: a -> b

5. DataKinds

Category: Type-Level Programming
Scope: Haskell
How to Enable: {-# LANGUAGE DataKinds #-}

When to Use:
For type-level programming with promoted data constructors.

Usage Example:

data Nat = Zero | Succ Nat
data Vec (n :: Nat) a = ...

6. ViewPatterns

Category: Pattern Matching
Scope: Haskell
How to Enable: {-# LANGUAGE ViewPatterns #-}

When to Use:
When pattern matching requires function application results.

Usage Example:

f (length -> 0) = "Empty"
f _ = "Not Empty"

7. PatternSynonyms

Category: Pattern Matching
Scope: Haskell
How to Enable: {-# LANGUAGE PatternSynonyms #-}

When to Use:
To simplify or abstract complex patterns.

Usage Example:

pattern Zero <- 0
pattern Succ n <- (n + 1)

8. OverloadedStrings

Category: Literals
Scope: Haskell
How to Enable: {-# LANGUAGE OverloadedStrings #-}

When to Use:
When using string literals as Text, ByteString, etc.

Usage Example:

myText :: Text
myText = "hello"

9. TemplateHaskell

Category: Meta-programming
Scope: Haskell
How to Enable: {-# LANGUAGE TemplateHaskell #-}

When to Use:
For compile-time code generation (e.g., JSON derivation).

Usage Example:

$(deriveJSON defaultOptions ''MyType)

10. RecordWildCards

Category: Records
Scope: Haskell
How to Enable: {-# LANGUAGE RecordWildCards #-}

When to Use:
To reduce boilerplate in record pattern matching.

Usage Example:

printPerson Person{..} = putStrLn name

11. KindSignatures

Category: Type-Level Programming
Scope: Haskell
How to Enable: {-# LANGUAGE KindSignatures #-}

When to Use:
To explicitly specify the kind of a type parameter.

Usage Example:

data Proxy (a :: *) = Proxy

12. ScopedTypeVariables

Category: Type System
Scope: Haskell
How to Enable: {-# LANGUAGE ScopedTypeVariables #-}

When to Use:
When you need to reuse type variables across scopes.

Usage Example:

f :: forall a. a -> a
f x = let g :: a -> a
g y = y in g x

13. RankNTypes

Category: Type System
Scope: Haskell
How to Enable: {-# LANGUAGE RankNTypes #-}

When to Use:
When you need higher-rank polymorphism in function types.

Usage Example:

f :: (forall a. a -> a) -> Int

14. OverloadedLists

Category: Literals
Scope: Haskell
How to Enable: {-# LANGUAGE OverloadedLists #-}

When to Use:
To allow list literals to work with any IsList type.

Usage Example:

myVec :: Vector Int
myVec = [1, 2, 3]

15. DeriveGeneric

Category: Deriving
Scope: Haskell
How to Enable: {-# LANGUAGE DeriveGeneric #-}

When to Use:
To derive Generic instance for use with libraries like Aeson.

Usage Example:

data Person = Person String Int deriving (Generic)

16. StandaloneDeriving

Category: Deriving
Scope: Haskell
How to Enable: {-# LANGUAGE StandaloneDeriving #-}

When to Use:
To derive instances for types declared elsewhere or abstract.

Usage Example:

deriving instance Show MyType

17. LambdaCase

Category: Pattern Matching
Scope: Haskell
How to Enable: {-# LANGUAGE LambdaCase #-}

When to Use:
For concise anonymous functions with pattern matching.

Usage Example:

f = \case Just x -> x; Nothing -> 0

18. QuasiQuotes

Category: Meta-programming
Scope: Haskell
How to Enable: {-# LANGUAGE QuasiQuotes #-}

When to Use:
To embed DSLs or formatted literals inside Haskell code.

Usage Example:

[sql|SELECT * FROM users|]

19. RebindableSyntax

Category: Syntax
Scope: Haskell
How to Enable: {-# LANGUAGE RebindableSyntax #-}

When to Use:
To override built-in Haskell syntax like if, do, etc.

Usage Example:

ifThenElse :: Bool -> a -> a -> a

20. NamedFieldPuns

Category: Records
Scope: Haskell
How to Enable: {-# LANGUAGE NamedFieldPuns #-}

When to Use:
When you want to write concise record pattern bindings.

Usage Example:

greet Person{name} = putStrLn name

21. NoImplicitPrelude

Category: Prelude Control
Scope: Plutus
How to Enable: {-# LANGUAGE NoImplicitPrelude #-}

When to Use:
When working with PlutusTx which provides a custom Prelude.

Usage Example:

-- disables standard Prelude
import PlutusTx.Prelude

22. TemplateHaskell

Category: Meta-programming
Scope: Plutus
How to Enable: {-# LANGUAGE TemplateHaskell #-}

When to Use:
Required by PlutusTx compiler to generate on-chain data encodings.

Usage Example:

$(PlutusTx.makeIsData ''MyDatum)

23. DeriveAnyClass

Category: Deriving
Scope: Plutus
How to Enable: {-# LANGUAGE DeriveAnyClass #-}

When to Use:
Used to derive PlutusTx typeclass instances like ToData and FromData.

Usage Example:

data MyDatum = ... deriving (Generic, ToData)

24. DeriveGeneric

Category: Deriving
Scope: Plutus
How to Enable: {-# LANGUAGE DeriveGeneric #-}

When to Use:
Needed for DeriveAnyClass to derive ToData and similar.

Usage Example:

data MyDatum = MyDatum Int deriving (Generic)

25. TypeApplications

Category: Type System
Scope: Plutus
How to Enable: {-# LANGUAGE TypeApplications #-}

When to Use:
Explicitly apply types in functions like toData, fromData.

Usage Example:

PlutusTx.toData @MyDatum datum

Clone this wiki locally