Last active
April 4, 2016 18:23
-
-
Save bhargavg/66d77a8b162740bc70999de3a9376389 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
func makePerson(name: String) -> (age: Int) -> (status: MaritalStatus) -> (requestIDs: [Int]) -> (address: Address) -> Person { | |
return { age in { status in { requestIDs in { address in | |
Person(name: name, age: age, status: status, requestIDs: requestIDs, address: address) | |
}}}} | |
} | |
func makeAddress(flatNo: String) -> (buildingName: String) -> Address { | |
return { buildingName in | |
Address(flatNo: flatNo, buildingName: buildingName) | |
} | |
} |
This file contains hidden or 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
func get<T, U>(box:[String: U], key: String) -> T? { | |
return box[key] as? T | |
} |
This file contains hidden or 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
let json: [String: Any] = [ | |
"name": "Bill", | |
"age": 47, | |
"status": "s", | |
"request_ids": [178, 249, 320, 4481], | |
"address": [ | |
"flat_no": "31/c", | |
"building_name": "Grand Arcade" | |
], | |
] | |
func parseAddress(dict: [String: String]) -> Address? { | |
return makeAddress <*> get(dict, key: "flat_no") | |
<*> get(dict, key: "building_name") | |
} | |
func parseStatus(value: String) -> MaritalStatus? { | |
switch value { | |
case "s": | |
return .Single | |
case "m": | |
return .Married | |
default: | |
return .None | |
} | |
} | |
func parsePerson<T>(dict: [String: T]) -> Person? { | |
return makePerson <*> get(dict, key: "name") | |
<*> get(dict, key: "age") | |
<*> get(dict, key: "status") <~~ parseStatus | |
<*> get(dict, key: "request_ids") | |
<*> get(dict, key: "address") <~~ parseAddress | |
} | |
print(parsePerson(json)!) |
This file contains hidden or 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
struct Person { | |
let name: String | |
let age: Int | |
let status: MaritalStatus | |
let requestIDs: [Int] | |
let address: Address | |
} | |
struct Address { | |
let flatNo: String | |
let buildingName: String | |
} | |
enum MaritalStatus { | |
case Married, Single | |
} |
This file contains hidden or 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
infix operator <*> { | |
associativity left | |
precedence 100 | |
} | |
// Operator that takes | |
// f: An optional function that takes A and returns B | |
// x: An optional value of type A | |
// | |
// and returns f(x) if both f and x are present | |
func <*><A, B>(f: (A -> B)?, x: A?) -> B? { | |
guard let f = f, x = x else { | |
return nil | |
} | |
return f(x) | |
} | |
infix operator <~~ { | |
associativity left | |
precedence 110 // higher than <*> precedence | |
} | |
// Operator that takes | |
// x: Optional value of type A | |
// f: Transformation function that maps from | |
// A to an Optional B (because the transformation can fail) | |
// | |
// and returns f(x) if x is present (applies the transformation) | |
func <~~<A, B>(x: A?, f: (A -> B?)) -> B? { | |
guard let x = x else { | |
return .None | |
} | |
return f(x) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment