pointfree 스타일과 non-unary arity를 쉽게 결합 할 수 있는지 확실하지 않습니다. 결과 및 구성 기능의 유형을해야 무엇을 먼저 생각 :
// Compose: (B -> C) -> (A -> B) -> A -> C
const compose = f => g => x => f(g(x))
// Add: A -> A -> A
const add = x => y => x + y
// Mul: A -> A -> A
const mul = x => y => x * y
// Add1: A -> A
const add1 = add(1)
// Add1AndMul: A -> A -> A
// because:
// Add1: A -> A
// Mul: A -> A -> A
const add_1_and_mul = compose(mul)(add1)
// Mul4: A -> A
const mul_4 = add_1_and_mul(3)
const result = mul_4(5) //> 20
Ramda이 uncurryN
그래서 당신이 compose
주위를 포장 할 수 있으며 결과 함수의 태닝을 제거있다.
const add_1_and_multiply = R.uncurryN(2, R.compose(R.multiply, R.add(1)))
let result2 = add_1_and_multiply(3, 5) //> 20
는 이전 기능을 구성하는 데 필요한 "체인"에 다른 기능을 추가합니다.
// Add1AndMul: A -> A -> A
const add1_mul = compose(mul)(add1)
이것은 우리가 원하는 서명입니다.
// 1 2 3
// Add1AndMulAndAdd: A -> A -> A -> A
// which is: | | |
// Add1: A -> A | |
// Mul: A -> A -> A |
// Add: A -> A -> A
그래서 어떻게 든 우리는 그 어떤 "포인트"가없는 과 을 통과해야합니다. 그냥 간단한 구성을 시도하고 그것을 분석하자 : 작성의
let add1_mul_add = compose(add)(add1_mul)
Remeber 서명 : (E -> F) -> (D -> E) -> D -> F
를! 단계에서 분석 :
- 우리는 대신
(E -> F)
(E -> F )
(A -> A -> A)
의 우리의 add
함수 서명을 공급 우리는
E = A
F = A -> A
우리는 (D -> E)
및 add1_mul
에 동일한 작업을 수행 결론(210) (D -> E )
(A -> A -> A)
우리는
D = A
E = A -> A
그러나 우리가 이미 모순을 볼 수 있다는 결론! 2 단계에서 결론은 1 단계에서 결론을 모순됩니다. E
은 A
및 A -> A
일 수 없습니다.
따라서 add
과 add1_mul
을 작성할 수없고 add1_mul_add
은 오류를 발생시킵니다.
문제를 해결하고 pointfree 스타일에 대한 약속을 어기도록 수정합시다.
const add1_mul_add = x => compose(add)(add1_mul(x))
나는 나의 점을 설명하기 위해 몇 가지 규칙을 깰 및 코드 서명을 혼합거야 :
x -> (A -> A -> A) -> (x -> A -> A) -> A -> A -> A
||
\/
x -> (A -> A -> A) -> (A -> A) -> A -> A -> A
(E -> F ) -> (D -> E) -> D -> F
그래서 우리는 우리의 올바른 작성 서명을 얻었다!
x
변수를 제거하여 pointfree로 되돌리려면 어떻게해야합니까? 우리는 예를 들어 ... 우리 예 오래 된 기능 구성과 같은 명백한 패턴을 찾아 볼 수 있습니다!
f(g(x)) => compose(f)(g)
그리고 우리는 우리의 새로운 add1_mul_add
에서이 패턴을 찾을 수 -
f = compose(add)
g = add1_mul
f(g(x)) = compose(add)(add1_mul(x))
을 우리가 pointfree 그것을 줄이고 우리가 우리의 새로운 add1_mul_add
기능을 가지고 :
const add1_mul_add = compose(compose(add))(add1_mul)
을하지만, 이봐 - 우리가 할 수있는 더 줄여라!
const add1_mul_add = compose(compose)(compose)(add)(add1_mul)
그리고 거기 우리는 이미 The Owl
의 이름으로 하스켈에 존재하는 것을 발견했다. 체인의 모든 새로운 기능, 당신은 올빼미 연산자의 높은 순서를 만들어야합니다, 지금
const owl = compose(compose)(compose)
그러나 :
우리는 단순히 자바 스크립트를 정의 할 수 있습니다.
const owl2 = compose(compose)(owl)
const add1_mul_add_mul = owl2(mul)(add1_mul_add)
const owl3 = compose(compose)(owl2)
const add1_mul_add_mul_add = owl3(add)(add1_mul_add_mul)
따라서 함수를 pointfree 스타일로 단항하는 것이 좋습니다. 또는 목록과 같은 다른 구조를 사용
const actions = [ add, mul, add, mul ]
const values = [ 1, 2, 3, 4 ]
const add_mul_add_mul = (...values) => zip(actions, values).reduce((acc, [action, value]) => action(acc, value), 0)
시도가 ((1, x)를 y를 추가) 다중 '에 대한 구성을 사용하는'대신'곱셈의 (Y ((1)를 추가, 배))''R. compose (R.multiply, R.add (1))' – Bergi
@Bergi 정확히 내 대답을 결론 지었다. –