Last active
September 19, 2019 08:36
-
-
Save yossan/4acba9dc90364034afbeeb9149d997b4 to your computer and use it in GitHub Desktop.
IO Monad with Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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