Skip to content

Instantly share code, notes, and snippets.

@mgadda
Last active December 31, 2019 17:20
Show Gist options
  • Save mgadda/eda6c9991e219aa9cbdb0fd4e05c4ba5 to your computer and use it in GitHub Desktop.
Save mgadda/eda6c9991e219aa9cbdb0fd4e05c4ba5 to your computer and use it in GitHub Desktop.
//
// 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