Skip to content

Commit

Permalink
currying and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ay42 committed May 24, 2024
1 parent 0fa0523 commit 45aed19
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
23 changes: 23 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Functional",
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "Functional",
targets: ["Functional"]),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "Functional"),
.testTarget(
name: "FunctionalTests",
dependencies: ["Functional"]),
]
)
32 changes: 32 additions & 0 deletions Sources/Functional/Currying/Curry.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

public func curry<A, B, C>(_ fn: @escaping (A, B) -> C) -> (A) -> (B) -> C {
{ (a: A) -> (B) -> C in { (b: B) -> C in fn(a, b) } }
}

public func curry<A, B, C, D>(_ fn: @escaping (A, B, C) -> D) -> (A) -> (B) -> (C) -> D {
{ (a: A) -> (B) -> (C) -> D in { (b: B) -> (C) -> D in { (c: C) -> D in fn(a, b, c) } } }
}

public func curry<A, B, C, D, E>(_ fn: @escaping (A, B, C, D) -> E) -> (A) -> (B) -> (C) -> (D) -> E {
{ (a: A) -> (B) -> (C) -> (D) -> E in { (b: B) -> (C) -> (D) -> E in { (c: C) -> (D) -> E in { (d: D) -> E in fn(a, b, c, d) } } } }
}

public func curry<A, B, C, D, E, F>(_ fn: @escaping (A, B, C, D, E) -> F) -> (A) -> (B) -> (C) -> (D) -> (E) -> F {
{ (a: A) -> (B) -> (C) -> (D) -> (E) -> F in { (b: B) -> (C) -> (D) -> (E) -> F in { (c: C) -> (D) -> (E) -> F in { (d: D) -> (E) -> F in { (e: E) -> F in fn(a, b, c, d, e) } } } } }
}

public func curry<A, B, C, D, E, F, G>(_ fn: @escaping (A, B, C, D, E, F) -> G) -> (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> G {
{ (a: A) -> (B) -> (C) -> (D) -> (E) -> (F) -> G in { (b: B) -> (C) -> (D) -> (E) -> (F) -> G in { (c: C) -> (D) -> (E) -> (F) -> G in { (d: D) -> (E) -> (F) -> G in { (e: E) -> (F) -> G in { (f: F) -> G in fn(a, b, c, d, e, f) } } } } } }
}

public func curry<A, B, C, D, E, F, G, H>(_ fn: @escaping (A, B, C, D, E, F, G) -> H) -> (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> H {
{ (a: A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> H in { (b: B) -> (C) -> (D) -> (E) -> (F) -> (G) -> H in { (c: C) -> (D) -> (E) -> (F) -> (G) -> H in { (d: D) -> (E) -> (F) -> (G) -> H in { (e: E) -> (F) -> (G) -> H in { (f: F) -> (G) -> H in { (g: G) -> H in fn(a, b, c, d, e, f, g) } } } } } } }
}

public func curry<A, B, C, D, E, F, G, H, I>(_ fn: @escaping (A, B, C, D, E, F, G, H) -> I) -> (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> I {
{ (a: A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> I in { (b: B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> I in { (c: C) -> (D) -> (E) -> (F) -> (G) -> (H) -> I in { (d: D) -> (E) -> (F) -> (G) -> (H) -> I in { (e: E) -> (F) -> (G) -> (H) -> I in { (f: F) -> (G) -> (H) -> I in { (g: G) -> (H) -> I in { (h: H) -> I in fn(a, b, c, d, e, f, g, h) } } } } } } } }
}

public func curry<A, B, C, D, E, F, G, H, I, J>(_ fn: @escaping (A, B, C, D, E, F, G, H, I) -> J) -> (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J {
{ (a: A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J in { (b: B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J in { (c: C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J in { (d: D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J in { (e: E) -> (F) -> (G) -> (H) -> (I) -> J in { (f: F) -> (G) -> (H) -> (I) -> J in { (g: G) -> (H) -> (I) -> J in { (h: H) -> (I) -> J in { (i: I) -> J in fn(a, b, c, d, e, f, g, h, i) } } } } } } } } }
}
36 changes: 36 additions & 0 deletions Sources/Functional/Currying/Uncurry.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

public func uncurry<A, B, C>(_ fn: @escaping (A) -> (B) -> C) -> (A, B) -> C {
{ (a: A, b: B) -> C in fn(a)(b) }
}

public func uncurry<A, B, C, D>(_ fn: @escaping (A) -> (B) -> (C) -> D) -> (A, B, C) -> D {
{ (a: A, b: B, c: C) -> D in fn(a)(b)(c) }
}

public func uncurry<A, B, C, D, E>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> E) -> (A, B, C, D) -> E {
{ (a: A, b: B, c: C, d: D) -> E in fn(a)(b)(c)(d) }
}

public func uncurry<A, B, C, D, E, F>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> F) -> (A, B, C, D, E) -> F {
{ (a: A, b: B, c: C, d: D, e: E) -> F in fn(a)(b)(c)(d)(e) }
}

public func uncurry<A, B, C, D, E, F, G>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> G) -> (A, B, C, D, E, F) -> G {
{ (a: A, b: B, c: C, d: D, e: E, f: F) -> G in fn(a)(b)(c)(d)(e)(f) }
}

public func uncurry<A, B, C, D, E, F, G, H>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> H) -> (A, B, C, D, E, F, G) -> H {
{ (a: A, b: B, c: C, d: D, e: E, f: F, g: G) -> H in fn(a)(b)(c)(d)(e)(f)(g) }
}

public func uncurry<A, B, C, D, E, F, G, H, I>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> I) -> (A, B, C, D, E, F, G, H) -> I {
{ (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) -> I in fn(a)(b)(c)(d)(e)(f)(g)(h) }
}

public func uncurry<A, B, C, D, E, F, G, H, I, J>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> J) -> (A, B, C, D, E, F, G, H, I) -> J {
{ (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) -> J in fn(a)(b)(c)(d)(e)(f)(g)(h)(i) }
}

public func uncurry<A, B, C, D, E, F, G, H, I, J, K>(_ fn: @escaping (A) -> (B) -> (C) -> (D) -> (E) -> (F) -> (G) -> (H) -> (I) -> (J) -> K) -> (A, B, C, D, E, F, G, H, I, J) -> K {
{ (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) -> K in fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j) }
}
4 changes: 4 additions & 0 deletions Sources/Functional/Functions/Constant.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

public func constant<A,B>(_ a: A) -> (B) -> A {
{ _ in a }
}
8 changes: 8 additions & 0 deletions Sources/Functional/Functions/Flip.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

public func flip<A, B, C>(_ f: @escaping (A) -> (B) -> C) -> (B) -> (A) -> C {
{ a in { b in f(b)(a) } }
}

public func flip<A, B, C>(_ f: @escaping (A, B) -> C) -> (B, A) -> C {
{ f($1, $0) }
}
4 changes: 4 additions & 0 deletions Sources/Functional/Functions/Identity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

public func identity<A>(_ a: A) -> A {
a
}
8 changes: 8 additions & 0 deletions Sources/Functional/Functions/Reverse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

public func reverse<A, B, C, D>(_ f: @escaping (A) -> (B) -> (C) -> D) -> (C) -> (B) -> (A) -> D {
{ a in { b in { c in f(c)(b)(a) } } }
}

public func reverse<A, B, C, D>(_ f: @escaping (A, B, C) -> D) -> (C, B, A) -> D {
{ f($2, $1, $0) }
}
18 changes: 18 additions & 0 deletions Tests/FunctionalTests/CurryingTests/CurryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import XCTest
import Functional

final class CurryTests: XCTestCase {
func testCurry() {
struct S3: Equatable {
let a: Int
let b: Double
let c: Bool
}

XCTAssert(curry(+)(1)(2) == 3)

XCTAssert(curry(S3.init)(1)(2.0)(true) == S3(a: 1, b: 2.0, c: true))
}
}


8 changes: 8 additions & 0 deletions Tests/FunctionalTests/CurryingTests/UncurryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import XCTest
import Functional

final class UncurryTests: XCTestCase {
func testUncurry() {
XCTAssert(uncurry(curry(*))(2,2) == 4)
}
}
12 changes: 12 additions & 0 deletions Tests/FunctionalTests/FunctionsTests/FlipTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import XCTest
import Functional

final class FlipTests: XCTestCase {
func testFlip() {
func append(s1: String, s2: String) -> String {
s1 + s2
}

XCTAssert(flip(append)("1", "2") == "21")
}
}

0 comments on commit 45aed19

Please sign in to comment.