using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Collections.Immutable; public class ImmutableDefaultDictionary : IEnumerable>, IString { public readonly TValue defaultValue; public readonly ImmutableDictionary dictionary; public ImmutableDefaultDictionary(TValue defaultValue) { this.defaultValue = defaultValue; this.dictionary = ImmutableDictionary.Empty; } public ImmutableDefaultDictionary(TValue defaultValue, ImmutableDictionary dictionary) { this.defaultValue = defaultValue; this.dictionary = dictionary; } public TValue this[TKey key] { get => dictionary.GetOrDefault(key, defaultValue); } public ImmutableDefaultDictionary Add(TKey key, TValue value) => new ImmutableDefaultDictionary(defaultValue, dictionary.Add(key, value)); public ImmutableDefaultDictionary SetItem(TKey key, TValue value) => new ImmutableDefaultDictionary(defaultValue, dictionary.SetItem(key, value)); public ImmutableDefaultDictionary Remove(TKey key) => new ImmutableDefaultDictionary(defaultValue, dictionary.Remove(key)); public IEnumerator> GetEnumerator() => dictionary.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => dictionary.GetEnumerator(); public ImmutableDefaultDictionaryLens< TKey, TValue, ImmutableDefaultDictionary> lens { get => this.ChainLens(x => x); } public override string ToString() => "ImmutableDefaultDictionary {\n" + this.Select(kvp => (ks: kvp.Key.ToString(), vs: kvp.Value.ToString())) .OrderBy(p => p.ks) .Select(p => $"{{ {p.ks}, {p.vs} }}") .JoinWith(",\n") + "\n}"; public string Str() => ToString(); } public static class ImmutableDefaultDictionaryExtensionMethods { public static ImmutableDefaultDictionary ToImmutableDefaultDictionary(this IEnumerable e, UValue defaultValue, Func key, Func value) => new ImmutableDefaultDictionary(defaultValue, e.ToImmutableDictionary(key, value)); public static ImmutableDefaultDictionary ToImmutableDefaultDictionary(this ImmutableDictionary d, TValue defaultValue) => new ImmutableDefaultDictionary(defaultValue, d); }