Algebraic Data Types

in 5 minutes

bool

bool

2

true, false

*bool

*bool

3

nil, true, false

type P struct {
    A bool
    B *bool
}
type P struct {
    A bool
    B *bool
}
P{A: false, B: nil}
P{A: false, B: &false}
P{A: false, B: &true}
P{A: true, B: nil}
P{A: true, B: &false}
P{A: true, B: &true}

6

type P struct {
    A bool
    B *bool
}

2 x 3 = 6

P{B: nil}
P{B: &false}
P{B: &true}
P{A: true}
P{A: false}
P{A: false, B: nil}
P{A: false, B: &false}
P{A: false, B: &true}
P{A: true, B: nil}
P{A: true, B: &false}
P{A: true, B: &true}
type P struct {
    A bool
    B *bool
    C bool
}
type P struct {
    A bool
    B *bool
    C bool
}

2 x 3 x 2 = 12

var F func(A bool) (B bool)
var F func(A bool) (B bool)
func identity(A bool) bool {
    return A
}

func not(A bool) bool {
    return !A
}

func alwaysTrue(A bool) bool {
    return true
}

func alwaysFalse(A bool) bool {
    return false
}

4

var F func(A bool) (B *bool)
var F func(A bool) (B *bool)
func identity(A bool) *bool { return &A }

func not(A bool) *bool { return !A }

func alwaysTrue(A bool) *bool { return &true }

func alwaysFalse(A bool) *bool { return &false }

func alwaysNull(A bool) *bool { return null }

func nilIfFalse(A bool) *bool { if !A { return nil } else { return &true } }

func nilIfTrue(A bool) *bool { if A { return nil } else { return &false } }

func nilIfFalseNot(A bool) *bool { if !A { return nil } else { return &false } }

func nilIfTrueNot(A bool) *bool { if A { return nil } else { return &true } }

9

var F func(A bool) (B *bool)
func identity(A bool) *bool { return &A }

func not(A bool) *bool { return !A }

func alwaysTrue(A bool) *bool { return &true }

func alwaysFalse(A bool) *bool { return &false }

func alwaysNil(A bool) *bool { return null }

func nilIfFalse(A bool) *bool { if !A { return nil } else { return &true } }

func nilIfTrue(A bool) *bool { if A { return nil } else { return &false } }

func nilIfFalseNot(A bool) *bool { if !A { return nil } else { return &false } }

func nilIfTrueNot(A bool) *bool { if A { return nil } else { return &true } }

3  = 9

2

var F func(A *bool) (B bool)
var F func(A *bool) (B bool)
func default(A *bool) bool { if A == nil { return false } else { return *A } }

func isNilOr(A *bool) bool { if A == nil { return true } else { return *A } }

func alwaysTrue(A *bool) bool { return true }

func alwaysFalse(A *bool) bool { return false }

func defaultOrNot(A *bool) bool { if A == nil { return false } else { return !*A } }

func isNullOrNot(A *bool) bool { if A == nil { return true } else { return !*A } }

func defaultAndNot(A *bool) bool { if A == nil { return true } else { return !*A } }

func isNilAndNot(A *bool) bool { if A == nil { return false } else { return !*A } }

2^3 = 8

type P struct {
    A bool
    B *bool
    C func(bool) *bool
}
type P struct {
    A bool
    B *bool
    C func(bool) *bool
}

2 x 3 x (3 ) = 54

2

Algebra

  • Product
  • Tech

Algebra

  • Product
  • Power

What is Plus or Sum?

https://slides.com/walterschulze/algebraic-data-types

type Result interface {
    isResult()
}

type Ok struct {
    Value string
}

func (Ok) isResult() {}

type Error struct {
    Value error
}

func (Error) isResult() {}

func doHttp() {
   switch res.(type) {
   case Error:
       // report error
   case Ok:
       // do something useful
   default:
       // panic
   }
}
data Result
    = Ok String 
    | Error String

doHttp =
    case res of

        Error err -> 
            -- report error

        Ok k -> 
            -- do something useful

        -- no panic

Ok + Error + ε

Ok + Error

Algebraic Data Types

By Walter Schulze