Haskell & Plutus Language Extensions - wimsio/universities GitHub Wiki

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

26. table

Extension Usage Example When to Use How to Enable Category Scope
GADTs
data Expr a where
  Lit :: Int -> Expr Int
  Add :: Expr Int -> Expr Int -> Expr Int
When you need more precise typing in data constructors (e.g., embedded DSLs). {-# LANGUAGE GADTs #-} Type System Haskell
TypeFamilies
type family F a :: *
type instance F Int = Bool
When you need type-level functions associated with type classes. {-# LANGUAGE TypeFamilies #-} Type System Haskell
MultiParamTypeClasses
class Convertible a b where
  convert :: a -> b
When a type class logically relates more than one type. {-# LANGUAGE MultiParamTypeClasses #-} Type Classes Haskell
FunctionalDependencies
class Convertible a b | a -> b where
  convert :: a -> b
To help GHC infer types in multi-parameter type classes. {-# LANGUAGE FunctionalDependencies #-} Type Classes Haskell
DataKinds
data Nat = Zero | Succ Nat
data Vec (n :: Nat) a = ...
For type-level programming with promoted data constructors. {-# LANGUAGE DataKinds #-} Type-Level Programming Haskell
ViewPatterns
f (length -> 0) = "Empty"
f _ = "Not Empty"
When pattern matching requires function application results. {-# LANGUAGE ViewPatterns #-} Pattern Matching Haskell
PatternSynonyms
pattern Zero <- 0
pattern Succ n <- (n + 1)
To simplify or abstract complex patterns. {-# LANGUAGE PatternSynonyms #-} Pattern Matching Haskell
OverloadedStrings
myText :: Text
myText = "hello"
When using string literals as `Text`, `ByteString`, etc. {-# LANGUAGE OverloadedStrings #-} Literals Haskell
TemplateHaskell
$(deriveJSON defaultOptions ''MyType)
For compile-time code generation (e.g., JSON derivation). {-# LANGUAGE TemplateHaskell #-} Meta-programming Haskell
RecordWildCards
printPerson Person{..} = putStrLn name
To reduce boilerplate in record pattern matching. {-# LANGUAGE RecordWildCards #-} Records Haskell
KindSignatures
data Proxy (a :: *) = Proxy
To explicitly specify the kind of a type parameter. {-# LANGUAGE KindSignatures #-} Type-Level Programming Haskell
ScopedTypeVariables
f :: forall a. a -> a
f x = let g :: a -> a
g y = y in g x
When you need to reuse type variables across scopes. {-# LANGUAGE ScopedTypeVariables #-} Type System Haskell
RankNTypes
f :: (forall a. a -> a) -> Int
When you need higher-rank polymorphism in function types. {-# LANGUAGE RankNTypes #-} Type System Haskell
OverloadedLists
myVec :: Vector Int
myVec = [1, 2, 3]
To allow list literals to work with any `IsList` type. {-# LANGUAGE OverloadedLists #-} Literals Haskell
DeriveGeneric
data Person = Person String Int deriving (Generic)
To derive `Generic` instance for use with libraries like Aeson. {-# LANGUAGE DeriveGeneric #-} Deriving Haskell
StandaloneDeriving
deriving instance Show MyType
To derive instances for types declared elsewhere or abstract. {-# LANGUAGE StandaloneDeriving #-} Deriving Haskell
LambdaCase
f = \case Just x -> x; Nothing -> 0
For concise anonymous functions with pattern matching. {-# LANGUAGE LambdaCase #-} Pattern Matching Haskell
QuasiQuotes
[sql|SELECT * FROM users|]
To embed DSLs or formatted literals inside Haskell code. {-# LANGUAGE QuasiQuotes #-} Meta-programming Haskell
RebindableSyntax
ifThenElse :: Bool -> a -> a -> a
To override built-in Haskell syntax like `if`, `do`, etc. {-# LANGUAGE RebindableSyntax #-} Syntax Haskell
NamedFieldPuns
greet Person{name} = putStrLn name
When you want to write concise record pattern bindings. {-# LANGUAGE NamedFieldPuns #-} Records Haskell
NoImplicitPrelude
-- disables standard Prelude
import PlutusTx.Prelude
When working with PlutusTx which provides a custom Prelude. {-# LANGUAGE NoImplicitPrelude #-} Prelude Control Plutus
TemplateHaskell
$(PlutusTx.makeIsData ''MyDatum)
Required by PlutusTx compiler to generate on-chain data encodings. {-# LANGUAGE TemplateHaskell #-} Meta-programming Plutus
DeriveAnyClass
data MyDatum = ... deriving (Generic, ToData)
Used to derive PlutusTx typeclass instances like `ToData` and `FromData`. {-# LANGUAGE DeriveAnyClass #-} Deriving Plutus
DeriveGeneric
data MyDatum = MyDatum Int deriving (Generic)
Needed for `DeriveAnyClass` to derive `ToData` and similar. {-# LANGUAGE DeriveGeneric #-} Deriving Plutus
TypeApplications
PlutusTx.toData @MyDatum datum
Explicitly apply types in functions like `toData`, `fromData`. {-# LANGUAGE TypeApplications #-} Type System Plutus
⚠️ **GitHub.com Fallback** ⚠️