하스켈이 왜 단일성 제한없이 반복 평가를 피할 수 없습니까?


14

나는 얼마전에 learnyouahaskell을 끝냈고 , Haskell Wiki가 묘사 한 것처럼 Monomorphism Restriction을 이해하려고 노력했습니다 . MR이 어떻게 반복적 인 평가를 막을 수 있는지 이해하고 있지만, 왜 반복적 인 평가를 더 간단한 방법으로 피할 수 없는지 모르겠습니다.

내가 염두에두고있는 구체적인 예는 위키에서 사용되는 예입니다.

f xs = (len,len)
  where
    len = genericLength xs

여기서 genericLengthtype은입니다 Num a => [b] -> a.

분명히 동일한 인수를 가진 동일한 함수이므로 genericLength xs평가하기 위해 한 번만 계산하면됩니다 (len,len). 그리고 우리는 그것을 f알기 위해 어떤 호출도 볼 필요가 없습니다 . 그렇다면 왜 Haskell이 MR과 같은 규칙을 도입하지 않고이 최적화를 수행 할 수 없습니까?

이 위키 페이지에 대한 토론은 그것이 Num구체적인 유형이 아닌 유형 클래스 라는 사실과 관련이 있다고 말하지만 컴파일 타임에 순수한 함수가 동일한 값을 반환한다는 것이 분명하지 않아야합니다. 똑같은 논증을 두 번 주었을 때 같은 구체적인 유형의 Num?

답변:


11

함수 이름은 같지만 인수는 같지만 다형성이기 때문에 반환 유형과 구현이 다를 수 있습니다. 그것은가 기대 맥락에서라고하면 의미 (Int, MyWeirdCustomNumType)반환 유형을, 그것의 구현 때문에, 두 번을 평가하는 (+)의는 Int의 구현과는 완전히 다르다 (+)에서 MyWeirdCustomNumType. 어떤 시점에서 물리적으로 다른 코드를 실행해야합니다.

그것이 Num타입 클래스 라는 것이 중요한 이유 입니다. 그것은 당신이 다른 유형에 대해 다른 구현을 가지고 있음을 의미합니다. 또한 f라이브러리에 있으면 컴파일 타임에 반환해야 할 모든 유형의 조합에 대해 알지 못합니다.

따라서 f어떤 리턴 유형을 사용해야하는지에 대한 호출을 볼 필요 가 있습니다. 대부분의 경우, 그것들이 동일 할 것으로 기대할 수 있기 때문에 기본적으로 단일성 제한을 설정합니다. 그렇지 않은 드문 경우에는 끌 수 있습니다. 실제로 프로그래머는 이런 상황을 유형 추론에 맡기는 경향이 없습니다.


의 가능성을 고려하지 않았습니다 f [] :: (Int, Float). 이제는 완벽합니다. 감사합니다.
Ixrec

1
It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.나는 그것을 보는 더 좋은 방법은 typeclass 인스턴스가 효과적으로 추가 인수 genericLength이며 컴파일러가 두 호출에서 동일한 인수임을 확신하지 못한다는 것입니다.
Doval

빠른 질문입니다. MonomorphismRestriction이 해제 된 경우 나중에 나중에 한 번만 a = uncurry (==) $ f [1, 2, 3]길이를 확인하도록 해당 호출 사이트를 최적화 할 수 [1, 2, 3]있습니까? 그렇다면 나는 왜 단일성 제한이 실제로 당신을 사고 있는지에 대해 혼란스러워합니다.
세미콜론
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.