Skip to content

Instantly share code, notes, and snippets.

@alonecuzzo
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alonecuzzo/1c63bf16b44fb76530ab to your computer and use it in GitHub Desktop.
Save alonecuzzo/1c63bf16b44fb76530ab to your computer and use it in GitHub Desktop.
Code from Functional Presentation
// paperlesspost.com/api/v100/event?id=3948
//{
// id: 3948,
// eventName: "The Party For the LOLZ",
// hostName: "datFoolCuzzo"
//
//}
protocol JSONDecodable {
static func decode(json: JSON) -> Self?
}
infix operator >>> { associativity left precedence 150 }
func >>><A,B>(a: A?, f: A -> B?) -> B? {
if let x = a {
return f(x)
} else {
return .None
}
}
func >>><A, B>(a: Result<A>, f: A -> Result<B>) -> Result<B> {
switch a {
case let .Value(x): return f(x.value)
case let .Error(error): return .Error(error)
}
}
//fmap
infix operator <^> { associativity left }
func <^><A,B>(f: A -> B, a: A?) -> B? {
if let x = a {
return f(x)
} else {
return .None
}
}
//apply
infix operator <*> { associativity left }
func <*><A,B>(f: (A -> B)?, a: A?) -> B? {
if let x = a, fx = f {
return fx(x)
} else {
return .None
}
}
typealias JSON = AnyObject
typealias JSONDictionary = Dictionary<String, JSON>
struct EventDetails: JSONDecodable {
let id: Int
let eventName: String
let hostName: String
static func create(id: Int)(eventName: String)(hostName: String) -> EventDetails {
return EventDetails(id: id, eventName: eventName, hostName: hostName)
}
static func decode(json: JSON) -> EventDetails? {
return JSONObject(json) >>> { d in
EventDetails.create <^> d["id"] >>> JSONInt <*> d["eventName"] >>> JSONString <*> d["hostName"] >>> JSONString
}
}
}
//enum Either<A,B> {
// case Left(A)
// case Right(B)
//}
final class Box<A> {
let value: A
init(_ value: A) {
self.value = value
}
}
enum Result<A> {
case Error(NSError)
case Value(Box<A>)
init(_ error: NSError?, _ value: A) {
if let error = error {
self = .Error(error)
} else {
self = .Value(Box(value))
}
}
}
func JSONInt(object: JSON) -> Int? {
return object as? Int
}
func JSONString(object: JSON) -> String? {
return object as? String
}
func JSONObject(object: JSON) -> JSONDictionary? {
return object as? JSONDictionary
}
//parseResponse
struct Response {
let data: NSData
var statusCode: Int = 500
init(_ data: NSData, urlResponse: NSURLResponse) {
self.data = data
if let urlResponse = urlResponse as? NSHTTPURLResponse {
self.statusCode = urlResponse.statusCode
}
}
}
func parseResponse(response: Response) -> Result<NSData> {
let validRange = 200..<300
if !contains(validRange, response.statusCode) {
return .Error(NSError())
}
return .Value(Box(response.data))
}
func decodeJSON(data: NSData) -> Result<JSON> {
var jsonError: NSError?
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &jsonError)
return resultFromOptional(json, jsonError!)
}
func parseResult<A: JSONDecodable>(data: NSData!, urlResponse: NSURLResponse!, error: NSError!) -> Result<A> {
let result = Result(error, Response(data, urlResponse: urlResponse))
return result >>> parseResponse >>> decodeJSON >>> decodeObject
}
func decodeObject<A: JSONDecodable>(json: JSON) -> Result<A> {
return resultFromOptional(A.decode(json), NSError())
}
func resultFromOptional<A>(optional: A?, error: NSError) -> Result<A> {
if let optional = optional {
return .Value(Box(optional))
} else {
return .Error(error)
}
}
func getEventDetails<A: JSONDecodable>(request: NSURLRequest, callback: (Result<A>) -> ()) {
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, urlResponse, error in
callback(parseResult(data, urlResponse, error))
}
task.resume()
}
class FUTURENETWORKING {
func foo() {
getEventDetails(NSURLRequest()) { (result: Result<EventDetails>) -> Void in
switch result {
case let .Error(error):
break
case let .Value(boxedEventDetails):
let eventDetails = boxedEventDetails.value
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment