2016-08-19 4 views
0

lodash 흐름 기능은 실제 작성 기능입니까, 아니면 하나처럼 보이지만 빠르게 실행되도록 최적화되어 있고 내가 기대했던 유연성을 희생합니까? 나는 흐름이 카레가 될 수있는 함수를 리턴 할 것으로 기대했지만 대신 Javascript의 arguments 키워드를 사용하는 함수를 돌려 주었다. 따라서 카레는 보류중인 인자가 있다는 것을 알 수 없으며 즉시 호출됩니다.흐름에 의해 반환 된 함수에서 lodash 카레가 작동하지 않습니다. FP 용 로다시 FP?

직관적으로 충분히 사용 :

var add = function(x, y) { return x + y }; var exclam = function(x) { return x.toString() + "!"; } exclam(1) // "1!" add(1,2) // 3 var add1 = FP.curry(add)(1); add1(4) // 5 var add1AndExclam = FP.flow([add1, exclam]) add1AndExclam(2) // "3!"

비 직관적 결과 :

addAndExclam = FP.flow([add, exclam]) // function(){var t=arguments,e=t[0];if(i&&1==t.length&&yi(e)&&e.length>=200)return i.plant(e).value();for(var u=0,t=r?n[u].apply(this,t):e;++u<r;)t=n[u].call(this,t);return t} addAndExclam(1,2) // "3!" add1AndExclamV2 = FP.curry(addAndExclam)(1) // "NaN!"

그것이 과잉 함수형 프로그래밍 패러다임에 도움이 또 다른 라이브러리를 찾을 수 있나요? 난 그냥 내 자신의 작곡을 채찍해야합니까? 이미 프로젝트에 있었기 때문에 lodash를 사용했습니다. 설명서는 흐름이 lodash의 구성이어야하는 것처럼 보입니다.

lodash의 데이터 인수를 카레로 처리하는 것이 정말 어렵다는 것을 알았습니다. (eachMyArrayName 바로 가기와 같은 것을 원했습니다.) curryRight 또는 lodash 객체 자리 표시 자 규칙을 사용하는지 여부.

lodash FP가 자동 curriable을 만들기 위해서입니까? 아니면 내가 뭔가 잘못하고 있으며, 그것은 주요 기능 프로그래밍 도우미로 사용할 수 있습니까?

편집 :

이 같은 기능을 래핑 할 수 있습니다에 내가 원하는하지만 보일러보고 코드를 가지고있는 메타 프로그래밍의 목적을 물리 칠 것 같으면

. ramda 나에게 직관적이었을 것입니다 무엇을하는 것처럼

add1AndExclamV2 = FP.curry(function(x, y) { return addAndExclam(x, y) })(1) add1AndExclamV2(2) "3!"

+1

정적 인 ty가 없기 때문에 카레가 매개 변수의 수를 말할 수 없습니다 pe 시스템을 자바 스크립트에서 사용하고 있으며 모든 기능은 가변적입니다. 함수의'.length' 속성은 단지 힌트 일 뿐이며 가변적 인, 깔끔하지 않은 함수를위한'compose' 함수에서 예상대로 설정하는 것은 쉽지 않습니다. Underscore/Lodash는 그렇지 않지만 Ramda는 이것을 통과합니다 (그러나 실패는 거의 없습니다). 'compose '는 미리 함수를 카레하면 예상대로 작동합니다. – Bergi

답변

0

이것은 단지 기본적인 기능 구성입니다. Lodash의 "flow"와 Rambda의 "pipe"는 적절하지 않은 일반 함수이기 때문에 아마도 이러한 함수의 이름을 지정하기가 어려울 것입니다. 그들은 "real compose function"이라는 문구에 real이라는 단어를 사용하는 것과 같은 방식으로 "진짜"가 아닙니다. 캐치는의 "바이너리"기능은 카레 형식이어야 대신

let f = (x,y) => ... 

let f = x => y => ... 

대신 튜플을 복용 -

당신은 단항 함수가 comp2 사용하여 바이너리 기능을 구성 할 수

함수 프로그래밍은 the lambda calculus에 뿌리가 있다는 것을 기억하십시오. 여기서 1 인수 이외의 것을 취하는 함수는 없습니다.

const curry = f => x => y => f (x,y) 
 
const comp = f => g => x => f (g (x)) 
 
const comp2 = comp (comp) (comp) 
 

 
var add = function(x, y) { return x + y }; 
 
var exclam = function(x) { return x.toString() + "!"; } 
 

 
console.log(exclam (1)) // "1!" 
 
console.log(add (1,2)) // 3 
 

 
var add1 = curry (add) (1) 
 
console.log(add1 (4)) // 5 
 

 
var addAndExclam = comp2 (exclam) (curry (add)) 
 
console.log(addAndExclam (1) (2)) // "3!"
나는 표현이 모든 것에 유형을 퍼팅


더 effecitvely 프로그램에 대해 당신에게

// curry :: ((a,b) -> c) -> a -> b -> c 
const curry = f => x => y => f (x,y) 

// comp :: (b -> c) -> (a -> b) -> (a -> c) 
const comp = f => g => x => f (g (x)) 

// comp2 :: (c -> d) -> (a -> b -> c) -> (a -> b -> d) 
const comp2 = comp (comp) (comp) 

// add :: (Number,Number) -> Number 
var add = function(x, y) { return x + y }; 

// exclam :: Number -> String 
var exclam = function(x) { return x.toString() + "!"; } 

console.log(exclam (1)) // "1!" 
console.log(add (1,2)) // 3 

// add1 :: Number -> Number 
var add1 = curry (add) (1) 
console.log(add1 (4)) // 5 

// addAndExlam :: Number -> Number -> String 
var addAndExclam = comp2 (exclam) (curry (add)) 
console.log(addAndExclam (1) (2)) // "3!" 
이유를하는 데 도움이 평가하는 방법 볼 수 substitution model를 사용하는 것이 좋습니다 귀하의 코멘트에 대해서는 088,243,210

:

내가 중첩 된 기능 중 하나는 두 개의 인수했다 특별한 기능을 구성하기를 원한다면, 내가

좋은 생각을 쓰는 것 같아요. 자신의 언어 나 도서관에서 제공하는 내장 프로 시저를 둘러 보았다면, 그것은 이미 당신이 그것을 먼저 써야한다는 것을 나타내는 지표 일 것입니다. 적어도 자신의 필요를 정확히 이해하고 있는지 확인하십시오.

const addAndExclam = (x,y) => exclam (add (x,y)) 

을 완벽하게 수용 그리고 나중에에 대한 comp2을 배우고 더 나은 코드를 조금 설명 할 수, 당신은 그것을 구현할 수 있음을 참조한다면이

const addAndExclam = x => y => exclam (add (x,y)) 

입니다 그 시간

const addAndExclam = comp2 (exclam) (curry (add)) 
+0

Ramda의'pipe'는 * 실제 * 합성 함수입니다. 뒤집힌 매개 변수를 가진'compose'가 "pipe"로 알려져 있기 때문에 그렇게 명명되었습니다. – Bergi

+0

나는 콘솔에서 그걸 가지고 놀아야했는데 마침내 머리를 감쌌다. 그래서 람다는 좀 더 유연하게하기 위해 약간 뒤에서 여분의 작업을하고 있습니다. 그러나 comp (비디오에서 보았던 것)의 정의에 따라 반환 된 최종 함수가 하나 이상의 인수를 취해야한다는 것을 알 수있는 방법이 없습니다. comp.f => g => (x, y) => f (g (x, y))로 호출 할 함수를 명시 적으로 작성해야합니다. 그 흥미 롭군요. – Wumbo

+0

반면에 args를 표시 할 수는 있지만 아무런 문제가 없습니다. }}) ---- (splat (splat)() {}}}}}}}} 나는 crockford에서 도난 당했다. ... ES6의 주장들 ... – Wumbo

0

var myAdd = function(x, y) { return x + y; }; var exclam = function(x) { return x.toString() + '!'; }; var addSclam = pipe(myAdd, exclam); addSclam(1,2); // "3!" var add1Sclam = curry(addSclam)(1); add1Sclam(500); // "501!"

는 것 같습니다. 그것은 나의 프로젝트에 또 다른 1.2MB를 더한다. 그러나 나는 그것이 더 많거나 적게 lodash를 대체하기 위해 사용될 수 있었다고 생각한다.

+0

이 질문은 혼란 스럽습니다. 당신은 단항 함수'exclam'을 가진 이진 함수'myAdd'를 작성하려하고 있습니다. 그러므로 여러분은 문제가 있습니다. Rambda는이 경우 당신을위한 솔루션 *이 아닙니다. 함수형 프로그래밍에 대한 오해는 지속될뿐입니다. – naomik

+0

람다의'pipe'가 당신에게 "진짜 작성 기능"을 제공하고 있거나 더 직관적 인 일을하고 있다고 생각한다면 다시 자신을 속일 것입니다. – naomik

+0

add와 pow는 flow와 pipe의 작성 및 작성에 사용되며, 표준적인 생각이라고 생각합니다. 중요한 것은 외 부 함수가 하나의 인수를 가질 수 없다는 것이 아니라 파이프를 공급하는 단항을 반환한다는 것입니다. 직접 작성 기능을 작성하는 방법을 보여주는 예제는이를 명확하게 보여줍니다. 그래서 당신에게 내 질문은 외부 함수가 두 개의 인수를 취할 때 어떤 상황이 어렵게 만드는가라는 것입니다. 나는 무엇을 얻지 못합니까? 어쩌면 당신은 파이프와 흐름의 arg 순서에 혼란 스러울 것입니다. 그것들은 표준 구성의 반대입니다. – Wumbo