Haskell & Plutus Language Extensions - wimsio/universities GitHub Wiki
- 1. GADTs
- 2. TypeFamilies
- 3. MultiParamTypeClasses
- 4. FunctionalDependencies
- 5. DataKinds
- 6. ViewPatterns
- 7. PatternSynonyms
- 8. OverloadedStrings
- 9. TemplateHaskell
- 10. RecordWildCards
- 11. KindSignatures
- 12. ScopedTypeVariables
- 13. RankNTypes
- 14. OverloadedLists
- 15. DeriveGeneric
- 16. StandaloneDeriving
- 17. LambdaCase
- 18. QuasiQuotes
- 19. RebindableSyntax
- 20. NamedFieldPuns
- 21. NoImplicitPrelude
- 22. TemplateHaskell
- 23. DeriveAnyClass
- 24. DeriveGeneric
- 25. TypeApplications
- 26. Summary Table Cheat Sheet
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
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
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
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
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 = ...
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"
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)
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"
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)
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
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
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
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
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]
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)
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
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
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|]
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
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
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
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)
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)
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)
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
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 |