-
Notifications
You must be signed in to change notification settings - Fork 8
2016 08 09 cbk
baekkyu cho edited this page Aug 8, 2016
·
16 revisions
<요약>
- 꼬리재귀함수를 이용하여 loop를 작성하는 방법
- 고차함수 소개
- 다형적 고차함수의 예
// 주석
/* 주석 */
/** 주석 */
object MyModule { //object 키워드는 singleton 형식을 만든다. (java의 static과 비슷)
def abs(n: Int): Int = // 정수 하나를 받고, 절댓값을 돌려주는 순수함수
if (n < 0) -n // 등호(=) 기준으로 왼쪽을 좌변 또는 서명(signature), 오른쪽을 우변 또는 정의(definition)이라고 부른다.
else n // return 키워드는 없음. 우변의 평가결과가 곧 메서드의 반환값이다.
private def formatAbs(x: Int) = { // return형식은 타입추론이 가능하다.
val msg = "The absolute value of %d is %d"
msg.format(x, abs(x))
}
// java의 main메서드와 동일한 기능, 부수효과가 발생하기 때문에 절차(procedure), 불순함수(impure funtion)라고 부른다.
def main(args: Array[String]): Unit = //Unit은 java, c의 void와 같은 목적
println(formatAbs(-42))
}- 일반적으론 스칼라용 빌드도구인 sbt를 이용하는 것이 좋다.
- 간단한 방법은 스칼라 컴파일러를 이용하는 것이다.
// 컴파일 -> .class파일이 생성된다 (JVM에서 실행될 수 있는 java byte code로 컴파일됨)
> scalac MyModule
// 컴파일된 파일을 스칼라를 이용하여 실행
> scala MyModule
The absolute value of -42 is 42
// 직접 소스파일을 지정하여 스칼라 해석기(interpreter)로 실행하는것도 가능.
> scala MyModule.scala
The absolute value of -42 is 42
// 대화식모드 REPL(read-evaluate-print loop)을 이용하는 방법.
scala> :load MyModule.scala
Loading MyModule.scala...
defined object MyModule
scala> MyModule.abs(-42)
res0: Int = 42- 스칼라의 모든값은 **객체(object)**이다, 객체는 0개 또는 하나이상의 구성원(member)를 가질 수 있다.
- 2 + 1 같은 표현식도 object의 member를 호출하는 것이다. 해당표현식은 2.+(1)에 대한 구문적 겉치레(syntatic sugar)일 뿐이다.
- 스칼라에서는 연산자(operator)라는 개념이 존재하지 않는다.
- 인수가 하나인 메서드(method)는 마침표와 괄호를 생략한 중위(infix)표기법으로 호출이 가능하다.
- MyModule은 abs가 속한 이름공간(namespace) 이다.
- 자신의 member들에게 namespace를 제공해주는 것이 주된목적인 object를 흔히 **모듈(module)**이라고 부른다.
- 순수한 함수적 프로그램을 작성할 때에는 다른 함수를 인수로 받는 함수를 작성하는 것이 유용한 경우가 많다. 이런 함수를 고차함수(higher-order function)라고 부른다.
- 계승을 구하는 factorial 함수 작성
// loop를 함수적으로(loop 변수의 변이없이) 작성하는 방법은 재귀함수(recursive function)를 이용하는 것이다.
def factorial(n: Int): Int = {
@annotation.tailrec // 꼬리호출제거여부를 확인해주는 annotation
def go(n: Int, acc: Int): Int = //지역정의(local definition)
if (n <= 0) acc
else go(n-1, n*acc)
go(n, 1)
}- 재귀함수는 stackoverflow를 발생시킬 위험이 있다.
- 스칼라 컴파일러는 자기재귀(self-recursion)를 검출해서, 재귀호출이 꼬리위치(tail position)에서 일어난다면 바이트코드를 생성할 때, while loop와 같은 형태로 변환시켜 준다.
- factorial 함수를 추가함