Created
August 15, 2014 09:50
-
-
Save antmd/ff4f72f91cd7bd4f9b5d to your computer and use it in GitHub Desktop.
This file contains 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
import Foundation | |
// | |
// Box.swift | |
// swiftz_core | |
// | |
// Created by Andrew Cobb on 6/9/14. | |
// Copyright (c) 2014 Maxwell Swadling. All rights reserved. | |
// | |
// https://github.com/maxpow4h/swiftz/blob/master/swiftz_core/swiftz_core/Box.swift | |
// An immutable box, necessary for recursive datatypes (such as List) to avoid compiler crashes | |
public final class Box<T> { | |
private let _value : () -> T | |
public init(_ value : T) { | |
self._value = { value } | |
} | |
public var value: T { | |
return _value() | |
} | |
public func map<U>(f: T -> U) -> Box<U> { | |
return Box<U>(f(value)) // TODO: file rdar, type inf fails without <U> | |
} | |
} | |
enum Term { | |
case TmTrue | |
case TmFalse | |
case TmIf(Box<Term>, Box<Term>, Box<Term>) | |
case TmZero | |
case TmSucc(Box<Term>) | |
case TmPred(Box<Term>) | |
case TmIsZero(Box<Term>) | |
// We use Rob Rix’s Destructurable idea to be able to pattern match with boxed recursive enums. | |
// See the destructure() method below — converting this to an extension seems a good idea. | |
// https://github.com/robrix/Hammer.swift/blob/master/Hammer/Destructurable.swift | |
enum DestructuredTerm { | |
case TmTrue | |
case TmFalse | |
case TmIf(Term, Term, Term) | |
case TmZero | |
case TmSucc(Term) | |
case TmPred(Term) | |
case TmIsZero(Term) | |
} | |
func isnumericval () -> Bool { | |
switch (self) { | |
case TmZero: return true | |
case let TmSucc(t1): return t1.value.isnumericval() | |
default: return false | |
} | |
} | |
func isval () -> Bool { | |
switch (self) { | |
case TmTrue: return true | |
case TmFalse: return true | |
case let t where t.isnumericval(): return true | |
default: return false | |
} | |
} | |
func eval () -> Term { | |
switch self.destructure() { | |
case let .TmIf(t1, t2, t3): | |
return TmIf(Box(t1.eval()), Box(t2), Box(t3)) | |
case let .TmIf(.TmTrue, t2, _): | |
return t2 | |
case let .TmIf(.TmFalse, _, t3): | |
return t3 | |
case let .TmSucc(t1): | |
return TmSucc(Box(t1.eval())) | |
case let .TmPred(.TmZero): | |
return TmZero | |
case let .TmPred(TmSucc(nv1)) where nv1.value.isnumericval(): | |
return nv1.value | |
case let .TmPred(t1): | |
return TmPred(Box(t1.eval())) | |
case let .TmIsZero(TmZero): | |
return TmTrue | |
case let .TmIsZero(TmSucc(nv1)) where nv1.value.isnumericval(): | |
return TmFalse | |
case let .TmIsZero(t1): | |
return TmIsZero(Box(t1.eval())) | |
default: | |
fatalError("End of the line") | |
} | |
} | |
func destructure () -> DestructuredTerm { | |
switch self { | |
case TmTrue: return .TmTrue | |
case TmFalse: return .TmFalse | |
case TmZero: return .TmZero | |
case let TmSucc(t1): return .TmSucc(t1.value) | |
case let TmPred(t1): return .TmPred(t1.value) | |
case let TmIsZero(t1): return .TmIsZero(t1.value) | |
case let TmIf(t1, t2, t3): return .TmIf(t1.value, t2.value, t3.value) | |
} | |
} | |
} | |
/* Not needed anymore! :D | |
func ==(lhs: Term, rhs: Term) -> Bool { | |
switch (lhs, rhs) { | |
case (.TmTrue, .TmTrue): return true | |
case (.TmFalse, .TmFalse): return true | |
case (.TmZero, .TmZero): return true | |
case let (.TmSucc(l), .TmSucc(r)): return l.value == r.value | |
case let (.TmPred(l), .TmPred(r)): return l.value == r.value | |
case let (.TmIsZero(l), .TmIsZero(r)): return l.value == r.value | |
case let (.TmIf(l1, l2, l3), .TmIf(r1, r2, r3)): return l1.value == r1.value && l2.value == r2.value && l3.value == r3.value | |
default: return false | |
} | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment