Skip to content

Instantly share code, notes, and snippets.

@patrickbucher
Created November 4, 2022 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickbucher/70b8f1ebe91ea2f50cb829c7bad657a7 to your computer and use it in GitHub Desktop.
Save patrickbucher/70b8f1ebe91ea2f50cb829c7bad657a7 to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"fmt"
)
type Number float64
type Operator func(Number) Number
func Adder(i Number) Operator {
return func(n Number) Number {
return n + i
}
}
func Subtractor(i Number) Operator {
return func(n Number) Number {
return n - i
}
}
func Multiplier(i Number) Operator {
return func(n Number) Number {
return n * i
}
}
func Divider(i Number) Operator {
return func(n Number) Number {
return n / i // FIXME: divide by zero
}
}
// f(g(n))
func Compose(f, g Operator) Operator {
return func(n Number) Number {
x := g(n)
y := f(x)
return y
}
}
type Result struct {
Val Number
Err error
}
type LiftingOperator func(Number) Result
func LiftingAdder(i Number) LiftingOperator {
return func(n Number) Result {
return Result{n + i, nil}
}
}
func LiftingSubtractor(i Number) LiftingOperator {
return func(n Number) Result {
return Result{n - i, nil}
}
}
func LiftingMultiplier(i Number) LiftingOperator {
return func(n Number) Result {
return Result{n * i, nil}
}
}
func LiftingDivider(i Number) LiftingOperator {
return func(n Number) Result {
if i == 0 {
return Result{0.0, errors.New("divide by zero")}
}
return Result{n / i, nil}
}
}
func ComposeLifting(f, g LiftingOperator) LiftingOperator {
return func(n Number) Result {
x := g(n)
if x.Err != nil {
return Result{0.0, fmt.Errorf("call inner function: %w", x.Err)}
}
y := f(x.Val)
if y.Err != nil {
return Result{0.0, fmt.Errorf("call outer function: %w", y.Err)}
}
return Result{y.Val, nil}
}
}
func main() {
var n Number = 1
addTwo := Adder(2)
subOne := Subtractor(1)
mulThree := Multiplier(3)
divFour := Divider(4)
// ((((1 + 2) * 3) - 1) / 4) = 2.0
fmt.Println(divFour(subOne(mulThree(addTwo(n)))))
f := Compose(mulThree, addTwo)
g := Compose(subOne, f)
h := Compose(divFour, g)
fmt.Println(h(n))
//divZero := Divider(0)
//f = Compose(mulThree, addTwo)
//g = Compose(subOne, f)
//h = Compose(divZero, g) // NOTE: this would break everything
//fmt.Println(h(n))
addLiftingTwo := LiftingAdder(2)
subLiftingOne := LiftingSubtractor(1)
mulLiftingThree := LiftingMultiplier(3)
divLiftingFour := LiftingDivider(4)
fl := ComposeLifting(mulLiftingThree, addLiftingTwo)
gl := ComposeLifting(subLiftingOne, fl)
hl := ComposeLifting(divLiftingFour, gl)
fmt.Println(hl(n))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment