Skip to content

Instantly share code, notes, and snippets.

@haifengkao
Last active September 21, 2020 07:38
Show Gist options
  • Save haifengkao/4473173790ac3d74ced7c9f09f27eefe to your computer and use it in GitHub Desktop.
Save haifengkao/4473173790ac3d74ced7c9f09f27eefe to your computer and use it in GitHub Desktop.
point free exercise
import Foundation
infix operator <<<: CompositionPrecedence
precedencegroup CompositionPrecedence {
associativity: left
}
public func <<<<A, B, C>(
_ g: @escaping (B) -> C,
_ f: @escaping (A) -> B
) -> (A) -> C {
{ a in g(f(a)) }
}
precedencegroup FunctorPrecedence {
associativity: left
higherThan: DefaultPrecedence
}
/// Ap | Applies a function encapsulated by a functor to the value encapsulated by another functor.
infix operator <*> : FunctorPrecedence
/// Fmap | Maps a function over the value encapsulated by a functor.
infix operator <^> : FunctorPrecedence
/// Fmap | If the Optional is `.None`, ignores the function and returns `.None`. Else if the
/// Optional is `.Some`, applies the function to its value and returns the result in a new `.Some`.
public func <^> <A, B>(f : (A) -> B, a : A?) -> B? {
return a.map(f)
}
/// Ap | Returns the result of applying the given Optional function to a given Optional value. If
/// the function and value both exist the result is the function applied to the value. Else the
/// result is `.None`.
///
/// Promotes function application to an Optional function applied to an Optional value.
public func <*> <A, B>(f : ((A) -> B)?, a : A?) -> B? {
return f.flatMap { $0 <^> a }
}
/// Curries a 2-ary function.
///
/// - Parameter fun: Function to be curried.
/// - Returns: `fun` in curried form.
public func curry<A, B, C>(_ fun: @escaping (A, B) -> C) -> (A) -> (B) -> C {
{ a in { b in fun(a, b) }}
}
func isMultiple(other: Int, n: Int) -> Bool {
return n.isMultiple(of: other)
}
let isMultipleOf3 = curry(isMultiple(other:n:))(3)
let isMultipleOf5 = curry(isMultiple(other:n:))(5)
let fizz = {$0 ? "fizz" : nil} <<< isMultipleOf3
let buzz = {$0 ? "buzz" : nil} <<< isMultipleOf5
func merge(x: String?, y: String?) -> String? {
x?.appending(y ?? "") ?? y
}
func fizzbuzz(n: Int) -> String {
let a = fizz(n)
let b = buzz(n)
return (curry(merge(x:y:))(a)(b)) ?? n.description
}
(1...20).map(fizzbuzz)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment