//  Copyright © 2015 Rob Rix. All rights reserved.

public protocol TermContainerType: Equatable, CustomDebugStringConvertible, CustomStringConvertible {
	var out: Expression<Self> { get }
}

extension TermContainerType {
	public static func out(container: Self) -> Expression<Self> {
		return container.out
	}

	public func cata<Result>(transform: Expression<Result> -> Result) -> Result {
		return (Self.out >>> { $0.map { $0.cata(transform) } } >>> transform)(self)
	}

	public func para<Result>(transform: Expression<(Self, Result)> -> Result) -> Result {
		return (Self.out >>> { $0.map { ($0, $0.para(transform)) } } >>> transform)(self)
	}
}

public func == <Term: TermContainerType> (left: Term, right: Term) -> Bool {
	return left.out == right.out
}


public protocol TermType: IntegerLiteralConvertible, StringLiteralConvertible, TermContainerType {
	init(_: () -> Expression<Self>)
}

extension TermType {
	public init(_ expression: Expression<Self>) {
		self.init { expression }
	}
}


import Either
import Prelude

//  Copyright © 2015 Rob Rix. All rights reserved.

public protocol TermContainerType: Equatable, CustomDebugStringConvertible, CustomStringConvertible {
	var out: Expression<Self> { get }
}

extension TermContainerType {
	public static func out(container: Self) -> Expression<Self> {
		return container.out
	}

	public func cata<Result>(transform: Expression<Result> -> Result) -> Result {
		return (Self.out >>> { $0.map { $0.cata(transform) } } >>> transform)(self)
	}

	public func para<Result>(transform: Expression<(Self, Result)> -> Result) -> Result {
		return (Self.out >>> { $0.map { ($0, $0.para(transform)) } } >>> transform)(self)
	}
}

public func == <Term: TermContainerType> (left: Term, right: Term) -> Bool {
	return left.out == right.out
}


public protocol TermType: IntegerLiteralConvertible, StringLiteralConvertible, TermContainerType {
	init(_: () -> Expression<Self>)
}

extension TermType {
	public init(_ expression: Expression<Self>) {
		self.init { expression }
	}

	public static func ana<A>(transform: A -> Expression<A>)(_ seed: A) -> Self {
		return (Self.init <<< { $0.map(ana(transform)) } <<< transform)(seed)
	}
}


import Either
import Prelude

--- 
+++ 
@@ -31,10 +31,6 @@
 	public init(_ expression: Expression<Self>) {
 		self.init { expression }
 	}
-
-	public static func ana<A>(transform: A -> Expression<A>)(_ seed: A) -> Self {
-		return (Self.init <<< { $0.map(ana(transform)) } <<< transform)(seed)
-	}
 }
 
 
Remove ana (because nothing uses it).
