Skip to content

Instantly share code, notes, and snippets.

@pedrocid
Created April 2, 2018 14:22
Show Gist options
  • Save pedrocid/0f40945546398f893bbda4caea1888f1 to your computer and use it in GitHub Desktop.
Save pedrocid/0f40945546398f893bbda4caea1888f1 to your computer and use it in GitHub Desktop.
//Exercises from https://www.pointfree.co/episodes/ep9-algebraic-data-types-exponents
import UIKit
enum Either<A,B> {
case left(A)
case right(B)
}
struct Pair<A,B> {
let a: A
let b: B
}
// a^(b+c)= a^b*a^c
//Either<B,C> -> A = (B->A,C->A)
func to<A,B,C>(_ f: @escaping (Either<B,C>) -> A) -> ((B) -> A, (C) -> A) {
let fromBtoA = { b in
f(.left(b))
}
let fromCtoA = { c in
f(.right(c))
}
return (fromBtoA, fromCtoA)
}
func from<A,B,C>(_ f: ((B) -> A,(C) -> A)) -> (Either<B,C>) -> A {
return { either in
switch either {
case let .left(b):
return f.0(b)
case let .right(c):
return f.1(c)
}
}
}
//Example
let eitherToA: (Either<Int,Int>) -> String = { either in
switch either {
case let .left(b):
return "Left value \(b)"
case let .right(c):
return "Right value \(c)"
}
}
to(eitherToA)
from(to(eitherToA))
//(a*b)^c = a^c*b^c
//(a,b) <- c = (a <- c,b<-c)
//c -> (a,b) = (c -> a, c ->b)
// c -> Pair<A,B> = Pair<C->A,C->B>
func to<A,B,C>(_ f: @escaping (C) -> Pair<A,B>) -> Pair<(C)->A,(C)->B> {
let toA = { c in f(c).a }
let toB = { c in f(c).b }
return Pair(a: toA, b: toB)
}
func from<A,B,C>(_ f: Pair<(C)->A,(C)->B>) -> (C) -> Pair<A,B> {
return { c in
Pair(a: f.a(c),b: f.b(c))
}
}
//Example
let valueToPair: (Int) -> Pair<Int,Int> = { number in
return Pair(a: number/2, b: number % 2)
}
to(valueToPair)
from(to(valueToPair))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment