Haskell의 맥락에서 Y 조합자를 설명 할 때, 일반적으로 간단한 구현은 재귀 유형으로 인해 Haskell에서 유형 검사를하지 않습니다.
예를 들어, Rosettacode의 :
The obvious definition of the Y combinator in Haskell canot be used
because it contains an infinite recursive type (a = a -> b). Defining
a data type (Mu) allows this recursion to be broken.
newtype Mu a = Roll { unroll :: Mu a -> a }
fix :: (a -> a) -> a
fix = \f -> (\x -> f (unroll x x)) $ Roll (\x -> f (unroll x x))
실제로“명백한”정의는 유형 점검을하지 않습니다.
λ> let fix f g = (\x -> \a -> f (x x) a) (\x -> \a -> f (x x) a) g
<interactive>:10:33:
Occurs check: cannot construct the infinite type:
t2 = t2 -> t0 -> t1
Expected type: t2 -> t0 -> t1
Actual type: (t2 -> t0 -> t1) -> t0 -> t1
In the first argument of `x', namely `x'
In the first argument of `f', namely `(x x)'
In the expression: f (x x) a
<interactive>:10:57:
Occurs check: cannot construct the infinite type:
t2 = t2 -> t0 -> t1
In the first argument of `x', namely `x'
In the first argument of `f', namely `(x x)'
In the expression: f (x x) a
(0.01 secs, 1033328 bytes)
Ocaml에도 동일한 제한이 있습니다.
utop # let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g;;
Error: This expression has type 'a -> 'b but an expression was expected of type 'a
The type variable 'a occurs inside 'a -> 'b
그러나 Ocaml에서는 -rectypes
스위치 를 전달하여 재귀 유형을 허용 할 수 있습니다 .
-rectypes
Allow arbitrary recursive types during type-checking. By default, only recursive
types where the recursion goes through an object type are supported.
를 사용 -rectypes
하면 모든 것이 작동합니다.
utop # let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g;;
val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
utop # let fact_improver partial n = if n = 0 then 1 else n*partial (n-1);;
val fact_improver : (int -> int) -> int -> int = <fun>
utop # (fix fact_improver) 5;;
- : int = 120
타입 시스템과 타입 추론에 대해 궁금해해서 여전히 대답 할 수없는 몇 가지 질문이 제기됩니다.
- 먼저 타입 체커는 타입을
t2 = t2 -> t0 -> t1
어떻게 알 수 있습니까? 해당 유형을 생각해 낸 후 문제는 유형 (t2
)이 오른쪽에 자체를 참조한다는 것입니다. - 둘째, 아마도 가장 흥미로운 것은 Haskell / Ocaml 타입 시스템이 이것을 허용하지 않는 이유는 무엇입니까? Ocaml 은 스위치 가 주어지면 재귀 유형을 처리 할 수 있더라도 기본적으로 허용하지 않기 때문에 좋은 이유 가 있다고 생각 합니다.
-rectypes
이것들이 정말로 큰 주제라면 관련 문헌에 대한 조언을 부탁드립니다.