LithoOperators 0.1.4

LithoOperators 0.1.4

Maintained by Elliot Schrock.



LithoOperators

CI Status Version License Platform

Installation

LithoOperators is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'LithoOperators', git: 'https://github.com/ThryvInc/LithoOperators'

What's in this pod

This pod provides a bunch of quality-of-life improving functions and operators to make FP in Swift simpler.

infix operator >?>

This operator allows you to chain functions where optionality is an issue. For instance, suppose you had a function f which output a String? and another function g which only accepts a String; trying to use f >>> g would fail to compile, since you can't pass nil to g. By using f >?> g, however, will compile, since this operator only executes g if f returns a non-nil value. This is really nice paired with optionalCast defined below, which will try to cast an object for you. So for instance, suppose you had a function f from (UIButton) -> Void but wanted to be able to apply it intelligently to any UIView passed in; then you could do optionalCast >?> f and the compiler would return a function from UIView -> Void which, if the UIView is a UIButton in particular, would apply f to it.

func optionalCast<T, U>(object: U) -> T?

This is a really nice function that will cast objects for you. When paired with >?> the compiler will be able to tell what type to cast to without you saying explicitly.

infix operator >|>

This is basically an operator for currying. It puts the value a into the first postion of a function f from (A, B) -> C and returns a function that just accepts a value for B. In Prelude this would be a |> curry(f).

infix operator >||>

Similar to >|>, but with the second value. So consider f: (A, B) -> C. Then b >||> f will put b into the second argument of f and return a function from A -> C. I find this more ergonmic than using curry in this case, since I don't need to swap the arguments around or anything. The use case for this is mostly with the free map function defined below, so for instance, if you had a function f from Int -> String and wanted to use it to change an array of Ints to Strings, you could do so by saying: f >||> map which would return a function from [Int] -> [String]

infix operator >|||>

See above, convenient currying, but with more arguments.

infix operator >||||>

See above, convenient currying, but with more arguments.

infix operator >|||||>

See above, convenient currying, but with more arguments.

infix operator >||||||>

See above, convenient currying, but with more arguments.

func voidCurry<T, U>(_ t: T, _ f: @escaping (T) -> U) -> () -> U

This just returns a function that can be called without arguments at a later time with the passed in value prepopulated. I often use this when a reusable component shouldn't know the passed in type, but needs to pass it to other code when an action occurs.

infix operator *>

Operator version of voidCurry

prefix operator ^

An operator to create a function that, given a keypath for a type, will a function that will accept an object of that type and return the object's property's value. So for instance, ^\UIViewController.view will return a function (UIViewController) -> UIView. This comes from the excellent PointFree videos.

func union(_ functions: (() -> Void)...) -> () -> Void

Here, union will take a bunch of functions and return a function that, when called, will call each of those functions in the bunch. I use this mostly for UI styling, so for instance, for two functions called setClipsToBounds and setGrayBackground both of which are from UIView -> Void, then you could create a new function called, say, clipAndGrayBg = union(setClipsToBounds, setGrayBackground).

func coalesceNil<T>(with defaultValue: T) -> (T?) -> T

This just a function version of the nil coalescing operator ??

func ifExecute<T>(_ t: T?, _ f: (T) -> Void)

This function executes f if the value passed in is non-nil. Convenient when you have a function that accepts only non-optional values, but you have an unwrapped variable. Basically, this function unwraps optionals for you.

infix operator ?>

This is just an operator version of ifExecute.

func ifApply(_ condition: Bool, _ function: (Self) -> Self) -> Self

This is an extension function for a protocol named ConditionalApply. This function passes itself to the given function if the condition is true. I don't use it much in iOS, but it's pretty helpful in Vapor when creating database queries.

func firstElement<T>(_ array: [T]) -> T?

This returns the first element of an array, if that element exists

func map<U, V>(array: [U], f: (U) -> V) -> [V]

A free function version of map.

func map<Value>(_ kp: KeyPath<Element, Value>) -> [Value]

This is in an extension of Sequence and comes from the excellent PointFree videos. It allows you to transform arrays using keypaths.

func compactMap<Value>(_ kp: KeyPath<Element, Value?>) -> [Value]

Same as the previous, but with compactMap as the foundation instead.

func map<Element, Value>(array: [Element], _ kp: KeyPath<Element, Value>) -> [Value]

free function version of map with keypaths.

func fzip<T, U, V>(_ f: @escaping (T) -> U, _ g: @escaping (T) -> V) -> (T) -> (U, V)

This function zips together the outputs of some functions into a tuple. Very convenient when creating a view from a single model while keeping the two decoupled.

This pod also includes the functional getters/setters developed in the PointFree videos. So prop, get, set, over, mut, mver, and so on.

Author

Elliot Schrock

License

LithoOperators is available under the MIT license. See the LICENSE file for more info.