// Code quality of this file: medium. using System; using System.Collections.Immutable; public sealed class ImmutableDefaultDictionaryValueLens : ILens { public readonly Func, Whole> wrap; private readonly ImmutableDefaultDictionary oldDictionary; private readonly TKey oldKey; public TValue value { get => oldDictionary[oldKey]; } public ImmutableDefaultDictionaryValueLens(Func, Whole> wrap, ImmutableDefaultDictionary oldDictionary, TKey oldKey) { // TODO: check that key exists. this.wrap = wrap; this.oldDictionary = oldDictionary; this.oldKey = oldKey; } // Put methods with the following signature here to focus on sub-parts of the list as needed. // public ILens,Whole> sub-part => oldHole.sub-part.ChainLens(value => oldHole.with-sub-part(value)); public Whole Update(Func update) { var oldValue = oldDictionary[oldKey]; return wrap(oldDictionary.SetItem(oldKey, update(oldValue))); } public ImmutableDefaultDictionaryValueLens UpdateKey(Func update) { var newKey = update(oldKey); return new ImmutableDefaultDictionaryValueLens( wrap, oldDictionary.Remove(oldKey).Add(newKey, oldDictionary[oldKey]), newKey); } } public sealed class ImmutableDefaultDictionaryLens : ILens, Whole> { public readonly Func, Whole> wrap; private readonly ImmutableDefaultDictionary oldHole; public ImmutableDefaultDictionary value { get => oldHole; } public ImmutableDefaultDictionaryLens(Func, Whole> wrap, ImmutableDefaultDictionary oldHole) { // TODO: check that key exists. this.wrap = wrap; this.oldHole = oldHole; } // Put methods with the following signature here to focus on sub-parts of the list as needed. public ImmutableDefaultDictionaryValueLens this[TKey key] { get => new ImmutableDefaultDictionaryValueLens(wrap, oldHole, key); } public Whole Update(Func, ImmutableDefaultDictionary> update) { return wrap(update(oldHole)); } } public static class ImmutableDefaultDictionaryLensExtensionMethods { public static ImmutableDefaultDictionaryLens ChainLens( this ImmutableDefaultDictionary hole, System.Func, Whole> wrap) => new ImmutableDefaultDictionaryLens(wrap: wrap, oldHole: hole); // this is a shorthand since we don't have extension properties public static ImmutableDefaultDictionaryValueLens> lens( this ImmutableDefaultDictionary d, TKey key) => d.lens[key]; public static ImmutableDefaultDictionaryValueLens UpdateKey( this ImmutableDefaultDictionaryValueLens lens, TKey newKey) => lens.UpdateKey(oldKey => newKey); }