2017-11-28 16 views
2

내가 표준 ML에 새로 온 다음 코드표준 ML 구문

fun whilestat test stmt1 = 
     (fn x => if (test x) then (stmt1 x;whilestat test stmt1) else (x)); 
를 작성하려고

문제는 나에게 다음과 같은 오류

w.sml:21.6-22.82 Error: right-hand-side of clause doesn't agree with function result type [circularity] 
expression: ('Z -> 'Y) -> 'Z -> 'Z 
result type: ('Z -> 'Y) -> 'Z 
in declaration: 
whilestat2 = (fn arg => (fn <pat> => <exp>)) 

uncaught exception Error 
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27 
     ../compiler/TopLevel/interact/evalloop.sml:44.55 
     ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20 
을 제공한다는 것입니다 임 단지를 emaulate하려고

상태가 staement가 참이면 재귀하고, 그렇지 않으면 다시 값을 반환합니다.

+0

: 나는 아래 ???을 채우기 위해 노력하여 버그를 발견 코드의 버그). 나는 과거에 그 버그를 만났지만, 그 이후로 수정되었다고 확신합니다. 내가 사용하는 버전 (110.82)에서는 코드를 실행할 때 보조 오류 메시지가 표시되지 않습니다. –

답변

6

문제의 반환 유형은 whilestat입니다. then 분기에서는 함수를 반환하지만 else 분기에서는 임의의 데이터를 반환합니다. then 지점에서 재귀 할 때 모든 인수를 전달하는 것을 잊어 버린 것 같습니다.

내가 쓰는 방법은 다음과 같습니다 (fn x => ...을 사용할 필요가 없으므로 혼란 스럽습니다).

fun whilestat test stmt1 x = 
    if test x 
    then (stmt1 x; whilestat test stmt1 x) 
    else x 

추후에 추론을 다시 확인하기 위해 소스 코드에서 유형을 명시 적으로 주석 처리하는 것이 도움이 될 수 있습니다. (트리거 하나이기는하지만`캐치되지 않는 예외 error`는 SML/MJ 컴파일러 자체가 아니라 코드에 비해의 코드에서 버그를 나타냅니다

fun whilestat (test : 'a -> bool) (stmt1 : 'a -> unit) : ??? = 
    ... 
+0

당신이 의미하는 것이 확실하지 않습니다 --- whilestat는 함수 인 인수 (이 경우'test'와'stmt1')를 취하기 때문에 고차 함수입니다. 아마도 _currying_이라는 개념에 대해 읽는 것이 도움이 될 수 있습니다. 특히, 작은 예제로서,'fun f x = fn y => x + y'가'fun f x y = x + y'와 같다고 생각하십시오. –

+0

리플렉션에서 카레 함수는 인수의 유형에 관계없이 필연적으로 더 높은 순서라고 가정합니다. 이는 함수 유형의 값을 얻기 위해 부분적으로 적용 할 수 있기 때문입니다. 어쨌든, 나는 당신이 _currying_ 및 _partial application_에 관해 읽는 것이 도움이 될 것이라고 생각합니다. –