컴파일러는이 오류에 대해 불평하지만 최상위는 않습니다.
$ cat ungen.ml
open List
let oops = fold_left (fun a _ -> a + 1) 0
$ ocamlc -c ungen.ml
File "ungen.ml", line 2, characters 11-41:
Error: The type of this expression, '_a list -> int,
contains type variables that cannot be generalized
문제는 여전히 최상위 레벨에 있습니다. 당신이 목록 (안 제로 또는 2 개)의 단 하나의 유형 oops
를 사용하는 경우에는이 있음을
가
$ ocaml
OCaml version 4.01.0
# open List;;
# let oops = fold_left (fun a _ -> a + 1) 0;;
val oops : '_a list -> int = <fun>
# oops [1;2;3;4];;
- : int = 4
# oops ['a';'b';'c'];;
Error: This expression has type char but an expression was expected of type
int
#
참고 : 다른 종류의 두 개의리스트의 길이를 계산하는 oops
를 사용하지하려고하면 당신은 그것을 볼 것이다 오류. 컴파일러는 oops
(내 보낸 심볼)을 0 번 사용하면 전체 모듈을 볼 수 있고 oops
이 어떻게 사용되는지 알 수 있으므로 불평 할 수 있습니다. toplevel은 사용자가 다음에 입력 할 내용을 모르기 때문에 zero 용도에 대해 불평 할 수 없습니다.
죄송 업데이트, 나는 실제 오류가 무엇인지에 대한 자세한 내용을 말했다한다 (수준에서 나는 그것을 이해). 내 의견으로는 이것은 currying과 거의 관련이 없다.
이것은 유명한 "가치 제한"입니다. 값 제한에 대한 간단한 설명은 다음과 같습니다. 일반화 할 수없는 일부 표현식이 있습니다. 즉, 다형성으로 만들 수 없으므로 모든 유형과 함께 사용할 수 있습니다. 간단한 예를 들어이 같은 것입니다 : 당신이 유형 'a list ref
을 가지고 mylist
을 허용하는 경우
let mylist = ref []
, 당신은 안전하지 않습니다 그것의 모든 다른 유형의 목록을 저장할 수 있습니다.
그러나,이 일반화하는 것이 안전하다 : 유형 'a list
에 mylist2
을 일반화에 문제가 없습니다
let mylist2 = []
.
OCaml과 같은 현대의 ML 파생물에서 일반화에 대한 제한이 다소 단순한 규칙으로 축소되었습니다. "값"(예 : []
)을 일반화 할 수 있습니다. 값이 아닌 표현식 (예 : ref []
)은 일반화 할 수 없습니다.
식 :
fold_left (fun a _ -> a + 1) 0
값은 아니다. ref []
과 같은 거친 형태의 함수 응용 프로그램입니다. 이것은 (분명히) oops
의 정의입니다. 한편
, 식 :
fun xs -> fold_left (fun a _ -> a + 1) 0 xs
는 값이다; 그것은 람다입니다. 그래서 일반화 될 수 있습니다. 이것은 (편리한 구문 약어를 펼친 후에) 위의 len
의 정의입니다. 그래서 len
은 모든 목록에서 작동하지만 oops
은 그리 유용하지 않습니다.
값과 값이 아닌 값의 구별은 구문 론적입니다. 즉, 단지 표현의 형태를 국부적으로 바라 봄으로써 결정될 수있다. 결정을 내리는 데있어 표현의 유형이나 의미에 대해 알 필요가 없습니다.
현재 양식에서 값 제한을 사용하는 한 가지 인수는 대부분 oops
형식 대신 len
형태로 정의하여 함수의 원하는 일반화 (즉, 다형성)를 복구 할 수 있다는 것입니다. . 이 간단한 변환을 "η 확장"이라고합니다.
η 확장은 구문 만 변경하지만 함수의 의미는 변경하지 않는다는 사실은 값 제한이 근사치임을 보여줍니다. 즉, 일반화하기에 안전 할 수있는 몇 가지 표현을 일반화하는 것을 금지합니다. 그러나 실제 프로그램에서 발생하는 경우에는 너무 간단하지 않고 제한적이지 않습니다.
OCaml 3.07 이후 OCaml의 값 제한이 기본 ML보다 향상되어 많은 경우에 일반화가 가능해졌습니다. 여기에서 읽을 수 있습니다 : J. Garrigue, Relaxing the Value Restriction. 이 논문은 또한 가치 제한과 그 역사에 대한 탁월한 캡슐 요약을 포함하고 있습니다.
안녕하세요. Jeffrey, 답변 해 주셔서 감사합니다. 하지만 기본적으로 컴파일러가 허용하지 않는 이유는 무엇입니까? 이 슬라이드의 머리에서, 그것은 "currying"과 관련된 것이기 때문에 ..? 나는 "currying"의 기본 개념을 알고 있지만, "currying"이이 맥락에서 중요한 이유는 모르겠습니다. – computereasy
이것은 정말 훌륭한 답변입니다! 정말 고마워 ! – computereasy