Swiftional introduces some functional primitives that complement the Swift standard library.
Created for writing Swift code with a slight touch of functional programming.
1.x.x – Swift 5.8
2.x.x – Swift 5.9
Converts an uncurried function to a curried function.
Example:
(A, B) -> R
becomes
(A) -> (B) -> R
Converts a curried function into an uncurried function.
Example:
(A) -> (B) -> R
becomes
(A, B) -> R
Partial application. Applies an argument to a function.
Example:
(A, B) -> R
with applied first argument becomes
(B) -> R
Identity combinator function. Returns the input without changing it.
The constant combinator function. Ignores the function arguments and always returns the provided value.
Flips the arguments of a function.
Example:
(A, B) -> R
becomes
(B, A) -> R
It calls the specified closure with the given attribute as its receiver and returns its result.
Ignores the function return and always returns Void
.
Weakifying function.
Example:
// Instead of this:
someObject.onActionClosure = otherObject.someFunc // `otherObject` captured by strong reference
// Use operator:
someObject.onActionClosure = weakify(otherObject) { $0.someFunc() } // `otherObject` is weakified, not captured by strong reference
Memoization function. Memoize wrapper intercepts calls you send to the function and attempts to reply with results from its internal cache. If it fails to find a cached result, it calls the work function and records the result of the computation in memory. Subsequent calls to the function with the same arguments can then be satisfied by fetching the result from memory, avoiding redundant computations. Memoization is one of the oldest and simplest tricks in computer science, trading memory for CPU cycles.
Example:
let memoizedSomeFunc = memoize(f: someFunc(_:))
print(memoizedSomeFunc(2))
print(memoizedSomeFunc(3))
print(memoizedSomeFunc(2)) // result fetched from memory
Standard memoization is not very good at memoizing recursive functions. Here is the recursive memoization function. It is represented as a primitive recursive function, where the memoization is done at each step of the recursion.
Example:
let memoizedFibonacci = rmemoize { fibonacci, n in n < 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2) }
print(memoizedFibonacci(42))
fold
Case analysis for the Bool
type. Applies the provided closures based on the value.
foldRun
Runs the provided closures based on the content of this value.
foldEither
Case analysis for the Bool
type. Applies the provided closures based on the value and return Either
.
fold
Case analysis for the Optional
type. Applies the provided closures based on the content of this Optional
value.apply
Calls the specified closure with the Self
value as its receiver and returns the Self
value.
applied
Calls the specified closure with the Self
value as its receiver and returns a copy of the Self
value.
Composes functions and returns a function that is the result of applying g
to the output of f
.
Composes functions and returns a function that is the result of applying g
to the output of f
.
Pipe forward. Applies an argument to a function.
Example. This:
let result = h(parameter: g(parameter: f(parameter: a)))
Can also be written as:
let result = a |> f |> g |> h
Pipe backward. Applies an argument to a function.
Example. This:
let result = h(parameter: g(parameter: f(parameter: a)))
Can also be written as:
let result = h <| g <| f <| a
Applies a function to an argument and returns a callable function.
Example. This:
let result = { a in f(parameter: a) }
Can also be written as:
let result = a |>> f
Applies a function to an argument and returns a callable function.
Example. This:
let result = { a in f(parameter: a) }
Can also be written as:
let result = f <<| a
Asynchronous function composition
Effectful function composition
Weakifying function.
Example:
// Instead of this:
someObject.onActionClosure = otherObject.someFunc // `otherObject` captured by strong reference
// Use operator:
someObject.onActionClosure = otherObject ?> { $0.someFunc() } // `otherObject` is weakified, not captured by strong reference
Weakifying function.
Example:
// Instead of this:
someObject.onActionClosure = otherObject.someFunc // `otherObject` captured by strong reference
// Use operator:
someObject.onActionClosure = otherObject ?>> { $0.someFunc } // `otherObject` is weakified, not captured by strong reference
The type Either
represents a value of one of these types, but not both: .left(Left)
or .right(Right)
.
The Either
type is shifted to the right by convention.
That is, the .left
constructor is usually used to hold errors or secondary data,
while .right
is used to store a "correct", primary value - one that can be worked on further.
Wordplay: "Right" also means "Correct".
Volodymyr Andriienko, [email protected]
VANavigator is available under the MIT license. See the LICENSE file for more info.
link |
Stars: 4 |
Last commit: 2 weeks ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics