| 이전 주제 보기 :: 다음 주제 보기 |
| 글쓴이 |
메시지 |
서성현
가입: 2005년 9월 29일 올린 글: 54
|
올려짐: 2005년10월8일 21:26 주제: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
분명 올바른 함수인데 컴파일이 안되네요.
아래에 쓰인 함수 exec(n)은 항상 int 0을 리턴하도록 만들어진 함수입니다.
| 코드: |
fun getInt(n) = n
fun getBool(n) = if n>0 then true else false
fun calc(n, get, f) = let val r = exec(n/2)
in f( get(r) ) end
and exec(0) = 0
| exec(n) = if n>=10 then let fun f(x) = x+0
in calc(n, getInt, f) end
else let fun f(x) = if x then 1 else 0
in calc(n, getBool, f) end
|
코드에 무슨 문제가 있나요?
nML 컴파일러로 컴파일해봤더니
마지막 줄에 쓰인 getBool을 걸고 넘어지네요;
| 코드: |
<neoseo@bacardi bugtest> nmlc bug.n
bug.n 10.39-46:
오류: int -> int 타입이어야 하는데 int -> bool 타입입니다.
|
|
|
| 위로 |
|
 |
이기석
가입: 2005년 10월 3일 올린 글: 33
|
올려짐: 2005년10월9일 1:21 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
| 서성현 씀: | | 코드: |
fun getInt(n) = n
fun getBool(n) = if n>0 then true else false
fun calc(n, get, f) = let val r = exec(n/2)
in f( get(r) ) end
and exec(0) = 0
| exec(n) = if n>=10 then let fun f(x) = x+0
in calc(n, getInt, f) end
else let fun f(x) = if x then 1 else 0
in calc(n, getBool, f) end
|
|
exec(n) 부분에서 calc의 두번째 인자로 넘겨준 getInt와 getBool의
타입이 각각 int -> int 와 int -> bool 로 다르기 때문에 타입이 맞지않아서
에러가 난 것 같네요. |
|
| 위로 |
|
 |
김덕환
가입: 2005년 8월 29일 올린 글: 190
|
올려짐: 2005년10월9일 1:27 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
| 서성현 씀: |
| 코드: |
fun getInt(n) = n
fun getBool(n) = if n>0 then true else false
fun calc(n, get, f) = let val r = exec(n/2)
in f( get(r) ) end
and exec(0) = 0
| exec(n) = if n>=10 then let fun f(x) = x+0
in calc(n, getInt, f) end
else let fun f(x) = if x then 1 else 0
in calc(n, getBool, f) end
|
nML 컴파일러로 컴파일해봤더니
마지막 줄에 쓰인 getBool을 걸고 넘어지네요;
| 코드: |
<neoseo@bacardi bugtest> nmlc bug.n
bug.n 10.39-46:
오류: int -> int 타입이어야 하는데 int -> bool 타입입니다.
|
|
타입 체킹은 기본적으로 수식에 포함된 항들의 타입 관계에 대한 연립 방정식을 세우고 푸는 것입니다.
예에서, nML 타입 시스템은 "fun calc (n, get, f) = let val r = exec (n / 2) in f (get r) end" 뿐만 아니라 and로 묶인 "calc (n, getInt, f)"와 "calc (n, getBool, f)"에서도 calc에 대한 방정식을 도출합니다. 도출된 연립 방정식에 따르면 calc의 두번째 인자의 타입이 int -> int이면서 동시에 int -> bool이어야 합니다. 따라서, 불능에 해당하는 경우로 위와 같은 에러 메시지를 냅니다.
아래의 실행 예제가 이해에 도움이 되지 않을까 합니다. foo의 타입이 어떻게 변하는지 주의해서 보시기 바랍니다.
| 코드: |
# fun foo _ = ();;
val foo: 'a -> unit = <fun>
# fun foo _ = () and bar _ = foo 1;;
val foo: int -> unit = <fun>
val bar: 'a -> unit = <fun>
# fun foo _ = () and bar _ = (foo 1 ; foo true);;
^^^^
오류: int 타입이어야 하는데 bool 타입입니다.
|
_________________ TheyAreAsSmartAsYouAre |
|
| 위로 |
|
 |
손님
|
올려짐: 2005년10월9일 2:00 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
| 김덕환 씀: | | 도출된 방정식에 따르면 calc의 두번째 인자의 타입이 int -> int이면서 동시에 int -> bool이어야 합니다. 따라서, 불능에 해당하는 경우로 위와 같은 에러 메시지를 냅니다. |
전 함수 calc 가 int * (int -> 'a) * ('a -> int) -> int 타입으로 정의되길 원했는데..
만약 그렇게 된다면 제가 윗글에 써 놓은 코드가 문제없이 실행될 수 있겠지요.
조교님이 써 주신 함수 foo의 예에서도 이런 결과가 나왔으면 좋겠거든요.
| 코드: | # fun foo _ = () and bar _ = (foo 1 ; foo true);;
val foo: 'a -> unit = <fun>
val bar: 'a -> unit = <fun> |
함수 foo의 타입이 이렇게 정의된다고 해도
코드가 실행되는데 오류가 생기는 건 아닐 텐데..
nML 컴파일러에서는 왜 이런 식으로 처리해주지 않는 것일까요.
무슨 특별한 이유가 있는 것인가요?
p.s. 늦은 시간에 친절한 답글 감사드립니다.  |
|
| 위로 |
|
 |
서성현
가입: 2005년 9월 29일 올린 글: 54
|
올려짐: 2005년10월9일 2:07 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
글쓰면서 로그인하는 걸 깜박했네요. 윗글은 제가 쓴 글입니다. ^^;
어쨌든.. 조교님이 들어주신 예의 경우
and를 쓰지 않고 대신 fun을 쓰는 방법으로 타입 문제를 해결할 수 있겠지요.
| 코드: | (* and 대신 fun을 사용하여 함수 bar를 정의하면 오류없이 정의됨 *)
# fun foo _ = () fun bar _ = (foo 1 ; foo true);;
val foo: 'a -> unit = <fun>
val bar: 'a -> unit = <fun> |
그런데 제가 쓴 코드의 경우 타입 문제를 어떻게 해결해야 할까요;
calc와 exec이 서로가 서로를 호출하는 상황이라
and를 쓰지 않고서는 도저히 함수의 정의가 불가능하거든요. |
|
| 위로 |
|
 |
김덕환
가입: 2005년 8월 29일 올린 글: 190
|
올려짐: 2005년10월9일 3:29 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
| 서성현 씀: |
nML 컴파일러에서는 왜 이런 식으로 처리해주지 않는 것일까요.
무슨 특별한 이유가 있는 것인가요?
|
nML 구현을 보며 확인한 것은 아닙니다만, 하나의 연립 방정식의 해를 구하기 때문이라고 생각합니다. 위의 경우에 사람은 프로그래머의 의도를 이해하기 때문에 그 연립 방정식을 적절히 쪼개어 여러 개의 연립 방정식으로 나누어 풀면 더 정확한 타입을 얻을 수 있다고 판단할 수 있습니다. 그러나, 기계는 특정한 패턴이 아닌 일반적인 경우에 쪼갤지 말지, 어떻게 쪼갤지 하는 판단을 자동적으로 하기는 매우 어려울 겁니다. _________________ TheyAreAsSmartAsYouAre |
|
| 위로 |
|
 |
김덕환
가입: 2005년 8월 29일 올린 글: 190
|
올려짐: 2005년10월9일 3:38 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
| 서성현 씀: |
그런데 제가 쓴 코드의 경우 타입 문제를 어떻게 해결해야 할까요;
calc와 exec이 서로가 서로를 호출하는 상황이라
and를 쓰지 않고서는 도저히 함수의 정의가 불가능하거든요.
|
아래 코드 정도로 의도하는 바를 표현하실 수 있지 않을까요?
| 코드: |
# fun calc' e (n, get, f) =
let
val r = e (n / 2)
in
f (get r)
end;;
val calc': (int -> 'a) -> int * ('a -> 'b) * ('b -> 'c) -> 'c = <fun>
# fun exec 0 = 0
| exec n =
if n >= 10 then
let
fun f x = x + 0
in
calc' exec (n, getInt, f)
end
else
let
fun f x = if x then 1 else 0
in
calc' exec (n, getBool, f)
end;;
val exec: int -> int = <fun>
# fun calc x = calc' exec x;;
val calc: int * (int -> 'a) * ('a -> 'b) -> 'b = <fun>
|
_________________ TheyAreAsSmartAsYouAre |
|
| 위로 |
|
 |
서성현
가입: 2005년 9월 29일 올린 글: 54
|
올려짐: 2005년10월9일 15:27 주제: Re: [nML질문] 분명 올바른 함수인데 컴파일이 안되네요. |
|
|
아.. 그런 방법이 있었군요;
제가 아직 nML 스타일의 코딩에 익숙하지 않아서 그런지
그런 방법은 떠올리지 못했네요.
인터프리터 숙제를 할 때 이것과 비슷한 문제 상황이 발생해서 한참 고민했었는데,
다음에 또 이런 문제가 생긴다고 해도 이젠 해결할 수 있을 것 같습니다.
조교님의 답변이 많은 도움이 되었습니다. 감사합니다. ^▽^ _________________ http://snupl.wo.to |
|
| 위로 |
|
 |
|