Last active
December 31, 2019 17:20
-
-
Save mgadda/eda6c9991e219aa9cbdb0fd4e05c4ba5 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// reduced_problem.swift | |
// swift-parse-playground | |
// | |
// Created by Matt Gadda on 12/27/19. | |
// | |
typealias IO<InputElement, OutputElement> = (AnyCollection<InputElement>) -> AnyCollection<OutputElement>? | |
func printConsumer<T: Collection>(_ source: T) -> AnyCollection<T.Element>? { | |
if let first = source.first { | |
print(first) | |
return AnyCollection(source).dropFirst(1) | |
} else { | |
return nil | |
} | |
} | |
func match<Element, PatternType: Collection>(iopattern pattern: PatternType) -> IO<Element, Element> | |
where Element == PatternType.Element, | |
Element : Equatable { | |
return { source in | |
if source.starts(with: pattern, by: { $0 == $1 }) { | |
return source.dropFirst(pattern.count) | |
} else { | |
return nil | |
} | |
} | |
} | |
func compose<T, U, V>(_ left: @escaping IO<T, U>, _ right: @escaping IO<U, V>) -> (AnyCollection<T>) -> AnyCollection<V>? { | |
return { source in | |
left(source).flatMap { | |
right($0) | |
} | |
} | |
} | |
func compose<T, U, V, IOConvertibleUV: IOConvertible>(_ left: @escaping IO<T, U>, _ right: IOConvertibleUV) -> (AnyCollection<T>) -> AnyCollection<V>? where IOConvertibleUV.InputElement == U, IOConvertibleUV.OutputElement == V { | |
return compose(left, right.mkIO()) | |
} | |
func compose<T, U, V, IOConvertibleTU: IOConvertible>(_ left: IOConvertibleTU, _ right: @escaping IO<U, V>) -> (AnyCollection<T>) -> AnyCollection<V>? where IOConvertibleTU.InputElement == T, IOConvertibleTU.OutputElement == U { | |
return compose(left.mkIO(), right) | |
} | |
func compose<IOConvertibleTU: IOConvertible, IOConvertibleUV: IOConvertible>(_ left: IOConvertibleTU, _ right: IOConvertibleUV) -> (AnyCollection<IOConvertibleTU.InputElement>) -> AnyCollection<IOConvertibleUV.OutputElement>? where IOConvertibleTU.OutputElement == IOConvertibleUV.InputElement { | |
return compose(left.mkIO(), right.mkIO()) | |
} | |
protocol IOConvertible { | |
associatedtype InputElement: Equatable | |
associatedtype OutputElement: Equatable | |
func mkIO() -> IO<InputElement, OutputElement> | |
} | |
extension Array : IOConvertible where Element: Equatable { | |
func mkIO() -> IO<Element, Element> { | |
return match(iopattern: self) | |
} | |
} | |
extension ArraySlice : IOConvertible where Element: Equatable { | |
func mkIO() -> IO<Element, Element> { | |
return match(iopattern: self) | |
} | |
} | |
func main() { | |
let process = compose([1,2], [3,4]) | |
let result = process(AnyCollection([1,2,3,4])) | |
print(Array(result!)) | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment