/// <summary> /// A limited form of traversal which traverses a <see cref="IFoldable{TSource}"/> structure and discards the results. /// </summary> /// <typeparam name="TSource">The type of the element in the input structure.</typeparam> /// <typeparam name="TResult">The type of the result of the action.</typeparam> /// <param name="applicative">The type of the applicative.</param> /// <param name="foldable">The object to fold.</param> /// <param name="f">The function to apply to each contained element.</param> public static IApplicative <Unit> TraverseDiscard <TSource, TResult>( this IFoldable <TSource> foldable, Type applicative, Func <TSource, IApplicative <TResult> > f) { return(foldable.Foldr( (x, acc) => f(x).ApRight(acc), Applicative.PureUnsafe(new Unit(), applicative))); }
private List <T> DrawArray <T>(List <T> array, bool isDict) where T : Injection, new() { Color oldColor = GUI.backgroundColor; for (int index = 0, realIndex = 0; index < array.Count; index++) { string styleName = null; T injection = array[index] ?? new T(); if (injection.Type == InjectionType.List || injection.Type == InjectionType.Dict) { if (injection is IFoldable) { IFoldable foldable = injection as IFoldable; if (foldable.IsFolded) { styleName = "As TextArea"; GUI.backgroundColor = Color.white * 0.8F; GUILayout.Space(-2F); } } } if (string.IsNullOrEmpty(styleName)) { GUILayout.BeginHorizontal(); } else { GUILayout.BeginHorizontal(styleName); } Undo.RecordObject(m_LuaInjectionData, "Injection.Count"); bool remove = GUILayout.Button("×", GUILayout.Width(20F), GUILayout.Height(14F)); GUILayout.Label("Type:", GUILayout.Width(40F)); Undo.RecordObject(m_LuaInjectionData, "Injection.Type"); injection.Type = (InjectionType)EditorGUILayout.EnumPopup(injection.Type, GUILayout.Width(75F)); if (injection.Type == InjectionType.List || injection.Type == InjectionType.Dict) { if (typeof(T) == typeof(Injection)) { injection.Type = InjectionType.String; } } GUI.enabled = index > 0; Undo.RecordObject(m_LuaInjectionData, "Injection.Up"); bool up = GUILayout.Button("▲", GUILayout.Width(20F), GUILayout.Height(14F)); GUI.enabled = index < array.Count - 1; Undo.RecordObject(m_LuaInjectionData, "Injection.Down"); bool down = GUILayout.Button("▼", GUILayout.Width(20F), GUILayout.Height(14F)); GUI.enabled = true; if (injection.Type == InjectionType.Space) { injection.Name = null; injection.Value = null; } else { if (isDict) { GUILayout.Label("Name:", GUILayout.Width(40F)); injection.Name = EditorGUILayout.TextField(injection.Name ?? "", GUILayout.MaxWidth(120F)); } else { GUILayout.Label("Index:", GUILayout.Width(40F)); GUI.enabled = false; EditorGUILayout.IntField(realIndex + 1, GUILayout.Width(30F)); GUI.enabled = true; } object value = injection.Value; object newValue; if (injection.Type == InjectionType.List || injection.Type == InjectionType.Dict) { newValue = value; bool valueIsDict = injection.Type == InjectionType.Dict; if (typeof(T) == typeof(Injection4)) { Injection4 inj = injection as Injection4; if (!(newValue is List <Injection3>)) { newValue = new List <Injection3>(); } inj.IsFolded = DrawArrayValue(newValue as List <Injection3>, valueIsDict, inj.IsFolded); } else if (typeof(T) == typeof(Injection3)) { Injection3 inj = injection as Injection3; if (!(newValue is List <Injection2>)) { newValue = new List <Injection2>(); } inj.IsFolded = DrawArrayValue(newValue as List <Injection2>, valueIsDict, inj.IsFolded); } else if (typeof(T) == typeof(Injection2)) { Injection2 inj = injection as Injection2; if (!(newValue is List <Injection1>)) { newValue = new List <Injection1>(); } inj.IsFolded = DrawArrayValue(newValue as List <Injection1>, valueIsDict, inj.IsFolded); } else if (typeof(T) == typeof(Injection1)) { Injection1 inj = injection as Injection1; if (!(newValue is List <Injection>)) { newValue = new List <Injection>(); } inj.IsFolded = DrawArrayValue(newValue as List <Injection>, valueIsDict, inj.IsFolded); } } else { newValue = DrawValue <T>(injection.Type, value); } if ((newValue != null && value != null) ? newValue.GetHashCode() != value.GetHashCode() : newValue != value) { injection.Value = newValue; } realIndex++; } GUILayout.EndHorizontal(); if (injection.Type == InjectionType.List || injection.Type == InjectionType.Dict) { if (injection is IFoldable) { IFoldable foldable = injection as IFoldable; if (foldable.IsFolded) { GUI.backgroundColor = oldColor; GUILayout.Space(-2F); } } } if (remove) { array.RemoveAt(index); index--; } else if (up) { array[index] = array[index - 1]; array[index - 1] = injection; } else if (down) { array[index] = array[index + 1]; array[index + 1] = injection; } else { array[index] = injection; } } return(array); }
/// <summary> /// A limited form of traversal which traverses a <see cref="IFoldable{TSource}"/> structure and discards the results. /// </summary> /// <typeparam name="TApplicative">The type of the applicative.</typeparam> /// <typeparam name="TSource">The type of the element in the input structure.</typeparam> /// <typeparam name="TResult">The type of the result of the action.</typeparam> /// <param name="foldable">The object to fold.</param> /// <param name="f">The function to apply to each contained element.</param> public static TApplicative TraverseDiscard <TApplicative, TSource, TResult>(IFoldable <TSource> foldable, Func <TSource, IApplicative <TResult> > f) where TApplicative : IApplicative <Unit> => (TApplicative)TraverseDiscard(foldable, typeof(TApplicative), f);
/// <summary> /// Maps each element of the structure to a monoid and then combines the elements /// using the monoid's <see cref="IMagma{T}.Op(T, T)"/> operation. /// </summary> /// <typeparam name="TSource">The type of elements contained in <paramref name="foldable"/>.</typeparam> /// <typeparam name="TMonoid">The monoid to which to mape the elements.</typeparam> /// <param name="foldable">The object to fold.</param> /// <param name="empty">The neutral element of the monoid.</param> /// <param name="f">The function that maps an element to a monoid.</param> public static TMonoid FoldMap <TSource, TMonoid>(this IFoldable <TSource> foldable, Func <TMonoid> empty, Func <TSource, TMonoid> f) where TMonoid : IMonoid <TMonoid> => foldable.FoldMap(new Monoid <TMonoid>(empty(), (x, y) => x.Op(y)), f);