Skip to content

Instantly share code, notes, and snippets.

@phronmophobic
Created April 7, 2019 23:51
Show Gist options
  • Save phronmophobic/ba04374c6004c30c0a990424d6ff4e34 to your computer and use it in GitHub Desktop.
Save phronmophobic/ba04374c6004c30c0a990424d6ff4e34 to your computer and use it in GitHub Desktop.
Swift Lens
import UIKit
protocol LensProtocol {
func lget(data: Any?) -> Any?;
func lset(data: Any?, val: Any?) -> Any?;
}
struct KeyLens<KeyType> : LensProtocol where KeyType : Hashable {
let key : KeyType;
func lget(data: Any?) -> Any? {
if let d = data as? Dictionary<KeyType, Any> {
return d[key];
} else {
print("oops!")
}
return nil;
}
func lset(data: Any?, val: Any?) -> Any?{
if let d = data as? Dictionary<KeyType, Any> {
var newd = d;
newd[key] = val;
return newd;
} else {
print("oops!")
}
return nil;
}
}
struct IndexLens : LensProtocol {
let index : Int;
func lget(data: Any?) -> Any? {
if let arr = data as? Array<Any?> {
return arr[index];
} else {
print("oops!")
}
return nil;
}
func lset(data: Any?, val: Any?) -> Any?{
if let arr = data as? Array<Any?> {
var newArr = arr;
newArr[index] = val;
return newArr;
} else {
print("oops!")
}
return nil;
}
}
struct ComposeLens : LensProtocol{
let lenses: [LensProtocol];
func lget(data: Any?) -> Any? {
var retData = data;
for lens in lenses {
retData = lens.lget(data: retData);
}
return retData;
}
func lset(data: Any?, val: Any?) -> Any? {
var retData = data;
var original_data : [(LensProtocol, Any?)] = [];
let outer_lenses = lenses[0..<lenses.count - 1];
for lens in outer_lenses{
original_data.append((lens, retData));
retData = lens.lget(data: retData);
}
retData = lenses.last?.lset(data: retData, val:val);
for (lens, original_datum) in original_data.reversed(){
retData = lens.lset(data: original_datum, val: retData);
}
return retData;
}
};
let todos = ["home": [ ["completed": false, "description": "cook"],
["completed": false, "description": "clean"]],
"work": [ ["completed": false, "description": "code"],
["completed": true, "description": "drink coffee"]]
];
print (todos);
let first_home_todo_completed_lens = ComposeLens(lenses: [KeyLens(key: "home"),
IndexLens(index: 0),
KeyLens(key: "completed")])
print(first_home_todo_completed_lens.lset(data: todos, val: true ));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment