Skip to content

Instantly share code, notes, and snippets.

@yossan
Last active September 19, 2019 08:36
Show Gist options
  • Save yossan/4acba9dc90364034afbeeb9149d997b4 to your computer and use it in GitHub Desktop.
Save yossan/4acba9dc90364034afbeeb9149d997b4 to your computer and use it in GitHub Desktop.
IO Monad with Swift
enum Pair<T, WORLD> {
case cons (T, WORLD) // (value, outside)
}
// Outside the computer
typealias WORLD = Any
// IO Monad Instance (a.k.a IO Action)
typealias IO<T> = (WORLD) -> Pair<T, WORLD>
// MARK: Basic monad functions
func unit<T>(_ value: T) -> IO<T> {
return { (world) in
return .cons(value, world)
}
}
func flatMap<A, B>(_ monadInstance: @escaping IO<A>) -> (@escaping (A) -> IO<B>) -> IO<B> {
return { (actionAB: @escaping (A) -> IO<B>) in
return { (world) in
let newPair = monadInstance(world)
switch newPair {
case .cons(let value, let newWorld):
return actionAB(value)(newWorld) //Pair<B, WORLD>
}
}// as (WORLD) -> Pair<B, WORLD>
}
}
// MARK: -- Sample
func read(file: String) -> IO<String> {
return unit("Welcome to Monad World")
}
func write(file: String) -> ((String) -> IO<Void>) {
return { (message) in
print(message)
return unit(Void())
}
}
func copy(from: String, to: String) -> IO<Void> {
return flatMap(read(file: from))({ (message) in return write(file: to)(message)
})
}
let copyAction = copy(from: "hello.txt", to: "hello.txt.bk")
_ = copyAction(Void())
@stefc
Copy link

stefc commented Dec 26, 2017

One Question to IO Monad :
How did I chain two equal monads together
for example I have a copyActionA and another copyActionB and I would execute at first 'a' and then 'b' and the result should be a third monad

If I understand this correct this should be a .map operation like a functor

let copyAction = copyActionB |< copyActionB 
_ = copyAction(Void())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment