Skip to content

Instantly share code, notes, and snippets.

@aaditmshah
Created June 12, 2024 04:03
Show Gist options
  • Save aaditmshah/3edcc12f722f7d8872ac7c490c0136a1 to your computer and use it in GitHub Desktop.
Save aaditmshah/3edcc12f722f7d8872ac7c490c0136a1 to your computer and use it in GitHub Desktop.
Design Patterns in Haskell

Design Patterns in Haskell

Creational Patterns

Factory Method

  1. Create a Product type class.
  2. Create an existential type SomeProduct for the Product type class.
  3. Create a Factory type class with a createProduct method.
class Product p where

data SomeProduct where
    SomeProduct :: Product p => p -> SomeProduct

class Factory f where
    createProduct :: f -> SomeProduct

Abstract Factory

  1. Create multiple Product type classes, e.g. ProductA and ProductB.
  2. Create an existential type for each type class, e.g. SomeProductA and SomeProductB.
  3. Create a Factory type class with one factory method for each product.
class ProductA p where

class ProductB p where

data SomeProductA where
    SomeProductA :: ProductA p => p -> SomeProductA

data SomeProductB where
    SomeProductB :: ProductB p => p -> SomeProductB

class Factory f where
    createProductA :: f -> SomeProductA
    createProductB :: f -> SomeProductB

Builder

  1. Create a Builder type class with methods for build steps, which return new builders.
  2. Create a Director type class with recipes created by composing Builder methods.
class Builder b where
    buildStart :: b
    buildStepA :: b -> b
    buildStepB :: b -> b
    buildStepZ :: b -> b

class Director d where
    makeFoo :: Builder b => d -> b -> b
    makeBar :: Builder b => d -> b -> b

Prototype

  1. Create a Prototype type class with a clone method.
  2. Create an existential type SomePrototype for the Prototype type class.
  3. Create a Registry type class with methods to get and set prototypes.
class Prototype p where
    clone :: p -> IO p

data SomePrototype where
    SomePrototype :: Prototype p => p -> SomePrototype

class Registry r where
    setPrototype :: Prototype p => r -> String -> p -> IO ()
    getPrototype :: r -> String -> IO (Maybe SomePrototype)

Singleton

Create a Singleton type class with a getInstance method.

class Singleton s where
    getInstance :: IO s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment