Swift3で継続モナドを書いてみる
Swift3で継続モナドを書いてみました。
contMonad.swift
import Foundation
typealias CPSCallBack<R> = (R)->Void
typealias CPSFunction<R> = (@escaping CPSCallBack<R>)->Void
class ContMonad<R> {
let cps: CPSFunction<R>
init(cps:@escaping CPSFunction<R>) {
self.cps = cps
}
func run(callBack:@escaping CPSCallBack<R>)->Void {
return cps(callBack)
}
func fmap<T>(_ f:@escaping (R)->T) -> ContMonad<T>{
return self >>= {(r:R) in unit(f(r))}
}
}
func >>=<R,T>(left:ContMonad<R>, right:@escaping (R)->ContMonad<T>) -> ContMonad<T> {
let f = {(cb:@escaping CPSCallBack<T>) -> Void in
left.run(callBack:{r in
let c:ContMonad<T> = right(r)
c.run(callBack:{t in
cb(t)
})
})
}
return ContMonad<T>(cps:f)
}
func unit<R>(_ x:R) -> ContMonad<R> {
let cps:(CPSCallBack<R>)->Void = {(cb:CPSCallBack<R>)->Void in
return cb(x)
}
return ContMonad<R>(cps:cps)
}
func fmap<R,T>(f:@escaping (R) -> T, m:ContMonad<R>) -> ContMonad<T> {
return m >>= {(r:R) in unit(f(r))}
}
func fmap<R,T>(f:@escaping (R)->T) -> (ContMonad<R>) -> ContMonad<T> {
return {m in fmap(f:f, m:m)}
}
enum CPSResult<X>{
case just(X)
case error(Error)
}
使用例として、IDを非同期で取得する関数、IDから非同期でレコードを取得する関数、結果の変換をする関数を定義し、最後に>>=つまりバインドでつなげます。
example.swift
func getRecordCont(uid:SomeUID?) -> ContMonad<CPSResult<SomeRecord>> {
return ContMonad{cb in
let cb_ = cb
DispatchQueue.global().async {
let r = SomeRecord(title: "\(uid?.uid) - record")
cb_(CPSResult.just(r))
}
}
}
func getUIDsCont()->ContMonad<CPSResult<SomeUID>> {
return ContMonad { cb in
DispatchQueue.global().async {
let r = SomeUID(uid: "PO")
cb(CPSResult.just(r))
}
}
}
func uidFromResult(_ r:CPSResult<SomeUID>) -> SomeUID? {
switch r {
case let .just(uid):
return uid
default:
return nil
}
}
var b = getUIDsCont().fmap(uidFromResult)
let c = b >>= getRecordCont
c.run { r in
print("ContMonad result = \(r)")
}
sleep(100)
まとめたものはこちらに
https://github.com/KatagiriSo/RDMonad/blob/master/RDMonad
Author And Source
この問題について(Swift3で継続モナドを書いてみる), 我々は、より多くの情報をここで見つけました https://qiita.com/KatagiriSo/items/50fa1888af9760835d11著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .