[개념잡기] 함수형 프로그래밍 - (7) go, pipe
서론
함수를 받아서 함수를 리턴하는 pipe
함수와, pipe
의 즉시 실행 함수형 go
함수에 대해 알아보자
함수형 프로그래밍
pipe
pipe
함수는 인자로 함수리스트를 받아 return 값을 다음 함수로 넘겨 결과로 함수를 리턴하는 함수이다. 기대하는 동작은 다음과 같다.
var _pipe = function(){}
var pipe = _pipe(function(a){return a + 1},function(a){return a * a})
console.log( pipe(1) ) // 4 (a + 1) * a
pipe
함수를 구현해보자. reduce
를 이용하여 순서대로 함수들을 수행해가면서 return 값을 다음 함수로 넘겨주는 코드로 작성해면 될 것같다.
const _pipe = function() {
var fns = arguments
return function(arg) {
return _reduce(fns, function(arg, fn){
return fn(arg)
}, arg)
}
}
var pipe = _pipe(function(a){return a + 1},function(a){return a * a})
console.log( pipe(1) ) // 4
go
go
함수는 pipe
함수의 즉시실행하는 케이스로 첫번째 인자로 초기값을, 두번째 인자부터 함수들의 리스트를 받아 함수리스트들을 pipe
함수에 인자로 넘기고 첫번째 인자로 받은 초기값으로 함수를 즉시 실행시킨다. 기대하는 동작을 보자.
const _go = function(){}
_go(1,
function(a){return a + 1},
function(a){return a * a},
console.log) // 4
go
함수를 구현해보자 pipe
함수를 이용하여 인자로 받은 함수리스트를 넘겨주면 될 것같다.
const _go = function() {
[arg, ...fns] = arguments
return _pipe.apply(null, fns)(arg)
}
여기서 apply
함수는 전 포스팅에서 다뤘던 call
함수와 같은 역할을 하는데 차이점은 call
은 파라미터를 하나씩 넘겨야 하지만 apply
는 배열형태로 파라미터를 넘길 수 있다.
코드 개선(1)
지난번까지 했던 30세 이상 유저의 이름을 가져오는 코드를 보자.
console.log(
_map(
_filter(users, function(user){ return user.age >= 30 }),
_get("name")
)
) // (4) ["QW", "WE", "ER", "AS"]
이 코드를 오늘 만든 go
함수를 이용하여 개선해보자.
_go(users,
function(users) {
return _filter(users, function(user){
return user.age >= 30
})
},
function(users) {
return _map(users, _get("name"))
},
console.log
) // (4) ["QW", "WE", "ER", "AS"]
전에 작성한 코드는 뭔가 안에서부터 밖으로 나가는 코드 느낌이라면, 이번에 작성한 코드는 체이닝하는 느낌이 들어 더 직관적이다.
위에 코드를 보면 공통점이 있다. users 배열을 받아 로직을 처리한후 값을 리턴한 다는 것이다. 이때 users 를 받는 평가시점을 늦추면 좀더 코드를 매끄럽게 작성할 수 있을것 같다. 그러기 위해 map
, filter
함수에 curryr
함수를 적용시켜 코드를 다시 한번 작성해보겠다.
const _filter = _curryr((list, predi) => {
var new_list = []
_each(list, (val) => {
if(predi(val)) {
new_list.push(val)
}
})
return new_list
})
const _map = _curryr((list, mapper) => {
var new_list = []
_each(list, (val) => {
new_list.push(mapper(val))
})
return new_list
})
_go(users,
_filter(user => user.age >= 30), // user
_map(_get("name")),
console.log) //(4) ["QW", "WE", "ER", "AS"]
훨씬 코드가 간결해진 것을 볼수 있다.
마무리
// 기존에 작성했던 코드
console.log(
_map(
_filter(user, function(user){ return user.age >= 30 }),
function(user) { return user.name }
)
)
// 개선한 코드
_go(users,
_filter(user => user.age >= 30), // user
_map(_get("name")),
console.log) //(4) ["QW", "WE", "ER", "AS"]
지금까지 명령형 코드를 함수형 코드로 작성해보았다.
'Study > VanillaJS' 카테고리의 다른 글
[개념잡기] 함수형 프로그래밍 - (9) 마무리 (0) | 2019.03.09 |
---|---|
[개념잡기] 함수형 프로그래밍 - (8) 다형성 높이기 (0) | 2019.03.08 |
[개념잡기] 함수형 프로그래밍 - (6) call (0) | 2019.03.06 |
[개념잡기] 함수형 프로그래밍 - (5) reduce (0) | 2019.03.04 |
[개념잡기] 함수형 프로그래밍 - (4) curry, curryr (0) | 2019.03.04 |