mirror of
https://github.com/github/semantic.git
synced 2024-11-25 21:43:07 +03:00
Cofree is not lazy.
This commit is contained in:
parent
841f7017c8
commit
b4dc1e7bf1
@ -4,18 +4,18 @@
|
|||||||
///
|
///
|
||||||
/// This type is dual to `Free`. Where `Free` is inhabited by syntax trees where some terms are replaced with `B`s, `Cofree` is inhabited by syntax trees where all terms are annotated with `B`s. In Doubt, this allows us to e.g. annotate terms with source range information, categorization, etc.
|
/// This type is dual to `Free`. Where `Free` is inhabited by syntax trees where some terms are replaced with `B`s, `Cofree` is inhabited by syntax trees where all terms are annotated with `B`s. In Doubt, this allows us to e.g. annotate terms with source range information, categorization, etc.
|
||||||
public enum Cofree<A, B> {
|
public enum Cofree<A, B> {
|
||||||
indirect case Unroll(B, Memo<Syntax<Cofree, A>>)
|
indirect case Unroll(B, Syntax<Cofree, A>)
|
||||||
|
|
||||||
public var unwrap: Syntax<Cofree, A> {
|
public var unwrap: Syntax<Cofree, A> {
|
||||||
switch self {
|
switch self {
|
||||||
case let .Unroll(_, rest):
|
case let .Unroll(_, rest):
|
||||||
return rest.value
|
return rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public init(_ annotation: B, @autoclosure(escaping) _ syntax: () -> Syntax<Cofree, A>) {
|
public init(_ annotation: B, _ syntax: Syntax<Cofree, A>) {
|
||||||
self = .Unroll(annotation, Memo(unevaluated: syntax))
|
self = .Unroll(annotation, syntax)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ public enum Cofree<A, B> {
|
|||||||
///
|
///
|
||||||
/// As this is the dual of `Free.iterate`, it’s unsurprising that we have a similar guarantee: coiteration is linear in the size of the constructed tree.
|
/// As this is the dual of `Free.iterate`, it’s unsurprising that we have a similar guarantee: coiteration is linear in the size of the constructed tree.
|
||||||
public static func coiterate(annotate: B -> Syntax<B, A>)(_ seed: B) -> Cofree {
|
public static func coiterate(annotate: B -> Syntax<B, A>)(_ seed: B) -> Cofree {
|
||||||
return .Unroll(seed, Memo { annotate(seed).map(coiterate(annotate)) })
|
return .Unroll(seed, annotate(seed).map(coiterate(annotate)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ extension Cofree: CustomDebugStringConvertible {
|
|||||||
|
|
||||||
extension Cofree {
|
extension Cofree {
|
||||||
public func map<Other>(transform: B -> Other) -> Cofree<A, Other> {
|
public func map<Other>(transform: B -> Other) -> Cofree<A, Other> {
|
||||||
return .Unroll(transform(extract), Memo { self.unwrap.map { $0.map(transform) } })
|
return .Unroll(transform(extract), unwrap.map { $0.map(transform) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ extension Cofree {
|
|||||||
|
|
||||||
/// Returns a new `Cofree` by recursively applying `transform` to each node, producing the annotations for the copy.
|
/// Returns a new `Cofree` by recursively applying `transform` to each node, producing the annotations for the copy.
|
||||||
public func extend<Other>(transform: Cofree -> Other) -> Cofree<A, Other> {
|
public func extend<Other>(transform: Cofree -> Other) -> Cofree<A, Other> {
|
||||||
return .Unroll(transform(self), Memo { self.unwrap.map { $0.extend(transform) } })
|
return .Unroll(transform(self), unwrap.map { $0.extend(transform) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new `Cofree` constructed by recursively annotating each subtree with itself.
|
/// Returns a new `Cofree` constructed by recursively annotating each subtree with itself.
|
||||||
@ -112,5 +112,4 @@ extension Cofree where B: Categorizable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
import Memo
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
Loading…
Reference in New Issue
Block a user