Swift中的函数延迟实例化路径

Swift中的函数延迟实例化路径,swift,functional-programming,lazy-initialization,Swift,Functional Programming,Lazy Initialization,我想要一种在Swift中轻松实例化“路径”或一系列字典的方法。例如,假设我有一个类,它存储了如下内容(稍微夸张): 如果没有某种嵌套的地狱金字塔,您将如何实现这一点?理想情况下,如果我访问了一个空的Dict,并且没有可用的Dict,我希望能够在路径中“动态”设置它。和“叶”数组相同 我想我希望的是某种infix操作符,它允许我这样做(假设infix:?>,): 或者,更好的是: func store(path:(first:T,second:T,third:T), object:U) { p

我想要一种在Swift中轻松实例化“路径”或一系列字典的方法。例如,假设我有一个类,它存储了如下内容(稍微夸张):

如果没有某种嵌套的地狱金字塔,您将如何实现这一点?理想情况下,如果我访问了一个空的
Dict
,并且没有可用的
Dict
,我希望能够在路径中“动态”设置它。和“叶”数组相同

我想我希望的是某种
infix
操作符,它允许我这样做(假设infix:
?>
):

或者,更好的是:

func store(path:(first:T,second:T,third:T), object:U) {
  paths[path.first] ?> [:] >> path.second ?> [:] >> path.third ?> [] >>> { u in u.append(object) }
}
我遇到的问题是,
Dict
Array
都是通过Swift中的值传递的。这迫使我进行一些认真的嵌套,以便正确设置“路径”,以便插入叶对象

可能我对Swift要求太高了,但作为一种半函数式语言,我一直认为必须有一种更简单的方法来实现这一点

使现代化 我已经非常非常接近了:

infix operator ?> { associativity left }
private func ?> <U,T>(var v:(d:[T:U], v:T), var r:U) -> U {
  if let dv = v.d[v.v] {
    return dv
  } else {
    v.d.updateValue(r, forKey: v.v)
    return r
  }
}

infix operator >< { associativity left }
private func >< <T,U>(t:T, u:U) -> (T,U) {
  return (t, u)
}

infix operator >>> { associativity left }
func >>> <T> (var v:T, f:(T -> ())) {
    f(v)
}
中缀运算符?>{左结合性}
私有函数?>(变量v:(d:[T:U],v:T),变量r:U)->U{
如果让dv=v.d[v.v]{
返回dv
}否则{
v、 d.updateValue(r,forKey:v.v)
返回r
}
}
中缀运算符>{左结合性}
私有函数>>(t:t,u:u)->(t,u){
返回(t,u)
}
中缀运算符>>>{左结合性}
func>>>(变量v:T,f:(T->()){
f(v)
}
从这里,我应该可以做这样的事情:

paths >< path.first ?> [:] >< path.second ?> [:] >< path.third ?> [] >>> { arr in arr.append(object) }
path>[:]>[:]>[]>>{arr.append中的arr(对象)}
这几乎奏效了。我得到的唯一错误是:

类型“[T]”的不可变值只有名为“append”的变异成员

我似乎无法在运算符中指定需要传入的字典是可变的。有什么想法吗

我还要承认,
中缀
操作符确实有点模糊了代码。但即便如此,我认为这比维护嵌套地狱所需的20多行代码要好得多,否则我将不得不编写嵌套地狱

更新2 它不起作用。它似乎可以工作,但我最终遇到了与以前相同的问题:通过中缀函数复制
Dict
Array
值。因此,在转换的每个“阶段”,我都在修改一个副本,而不是原始版本。问题是似乎没有办法通过引用将值传递出函数。只能通过引用将值传入函数(使用
inout

func store(path:(first:T,second:T,third:T), object:U) {
  paths[path.first] ?> [:] >> path.second ?> [:] >> path.third ?> [] >>> { u in u.append(object) }
}
infix operator ?> { associativity left }
private func ?> <U,T>(var v:(d:[T:U], v:T), var r:U) -> U {
  if let dv = v.d[v.v] {
    return dv
  } else {
    v.d.updateValue(r, forKey: v.v)
    return r
  }
}

infix operator >< { associativity left }
private func >< <T,U>(t:T, u:U) -> (T,U) {
  return (t, u)
}

infix operator >>> { associativity left }
func >>> <T> (var v:T, f:(T -> ())) {
    f(v)
}
paths >< path.first ?> [:] >< path.second ?> [:] >< path.third ?> [] >>> { arr in arr.append(object) }