-
Notifications
You must be signed in to change notification settings - Fork 36
9장 control abstraction
kingori
###9.1
function을 해부해 보면
- common part: 해당 funciton을 호출할 때 매번 같은 부분. 즉, function의 body
- non-common part: function 호출마다 달라질 수 있는 부분. function value를 인자로 받을 경우, 이 function value를 non-common part로 볼 수 있음.
higher-order function: function을 매개변수로 갖는 function. control abstraction을 가능케 하는 주인공!
###9.2
API, library 등에 higher order function을 잘 사용하면 client code를 간결하게 만들 수 있다. 끝.
###9.3
currying: 복수의 인자 목록을 갖는 function. 각 인자 목록은 ( ) 로 구분함
def curriedSum(x: Int)(y: Int) = x + y
val onePlus = curriedSum(1)_ // 여기서 parameter list 전체를 치환하는 뒷부분 _ 앞의 공백은 생략할 수 있다. 앞 부분의 () 때문으로 보임. cf. println_ (X) <- println_ 자체가 유효한 식별자 이므로
###9.4
loan pattern: control abstraction 패턴으로 보임. 리소스를 인자 function에 '꿔 주는' 패턴. ex) 스트림을 열고 닫는 function / 열린 스트림을 전달받아 뭔가를 하는 function
scala에선 하나의 parameter만 받을 땐 () 를 { } 로 바꿀 수 있음
println("Hello, world!" )
println { "Hello, world!" } //둘이 동일함
따라서 { } 로 뭔가 원래 문법틱하게 꾸미려면 single parameter만 받도록 구성해야 함. -> curring을 쓰면 됨 ==> 왠지 꼼수틱한데? 딱히 아래만 보면 별 차이가 없어보이긴 함.
def a( param1: Int, op: Int => Int ) = { op(param1) }
val b = a(3, _: Int => Int )
scala> b( _ * 2)
res9: Int = 6
scala> b { _ * 2 }
res10: Int = 6
def curr_a( param1: Int)(op: Int => Int ) = { op(param1) }
scala> curr_a(3) { _ * 2 }
res11: Int = 6
scala> curr_a(3) { x => x * 2 }
res12: Int = 6
scala> val curr_b = curr_a(3)_
curr_b: Int => Int => Int = <function1>
scala> curr_b ( _ * 2 )
res13: Int = 6
scala> curr_b { _ * 2 }
res14: Int = 6
###9.5
by-name parameter: 인자로 넘기는 function이 argument을 갖지 않을 때 표현식이 어색해지는 문제를 해결해 줌. function 정의 시 () 를 명시하지 않으면 됨.
def noByName( a: () => Boolean ) = a()
scala> noByName( () => true ) // 앞의 () => 가 보기싫다
res16: Boolean = true
scala> noByName( true )
<console>:10: error: type mismatch;
found : Boolean(true)
required: () => Boolean
noByName( true )
scala> def byName( a: => Boolean ) = a()
<console>:8: error: Boolean does not take parameters
def byName( a: => Boolean ) = a()
^
scala> def byName( a: => Boolean ) = a
byName: (a: => Boolean)Boolean
scala> byName( true )
res18: Boolean = true
만약 이렇게 하면?
scala> def noByName( a: () => Boolean ) = a // a만 도로 return하는 꼴.
noByName: (a: () => Boolean)() => Boolean
scala> noByName( true )
<console>:10: error: type mismatch;
found : Boolean(true)
required: () => Boolean
noByName( true )
^
scala> noByName( () => true )
res24: () => Boolean = <function0>
scala> noByName( () => true )()
res25: Boolean = true
http://daily-scala.blogspot.com/2009/12/by-name-parameter-to-function.html
질문 : 178pg, by-name type 은 뭔 소리인가?
by name parameter는 function을 넘기기 때문에 나중에 evalution되는 이점을 활용할 수 있음.
###9.6
currying과 by-name parameter는 control abstraction 구현에 도움을 준다.