2012-03-03 3 views
17

함수의 로컬 범위 (let 또는 where)에 적용되는 유형 클래스의 인스턴스를 정의하는 것입니다. 더 중요한 것은이 인스턴스의 함수를 클로저 (closure)로 만들고 싶습니다. 즉, 인스턴스가 정의 된 어휘 범위의 변수를 닫을 수 있어야합니다. 즉, 다음에 함수가 호출 될 때 인스턴스가 다르게 작동 할 수 있습니다.)."로컬"typeclass 인스턴스를 가질 수 있습니까?

간단한 사용 사례를 제공 할 수 있습니다. 형식 클래스를 기반으로하는 형식에서 작동하는 함수가 있다고 가정합니다. 이 예제에서는 제곱을 사용합니다. 인스턴스가 Num 인 모든 유형에서 작동합니다 (예, 제곱은 매우 간단하고 쉽게 다시 구현할 수 있지만 더 복잡 할 수 있습니다). 기존 기능을 그대로 사용하거나 변경하지 않고 다시 사용할 수 있어야합니다.

square :: Num a => a -> a 
square x = x * x 

이제이 조작을 모듈러 산술, 즉 더하기, 곱하기 등에서 사용하고자한다고 가정합니다. 이것은 고정 모듈로 기본으로 구현하기 쉽지만 다른 모듈러베이스로 재사용 할 수있는 일반적인 것을 갖고 싶습니다. 나는 이런 식으로 뭔가를 정의 할 수 있도록하려면 :

newtype ModN = ModN Integer deriving (Eq, Show) 

-- computes (x * x) mod n 
squareModN :: 
squareModN x n = 
    let instance Num ModN where 
    ModN x * ModN y = ModN ((x * y) `mod` n) -- modular multiplication 
    _ + _ = undefined   -- the rest are unimplemented for simplicity 
    negate _ = undefined 
    abs _ = undefined 
    signum _ = undefined 
    fromInteger _ = undefined 
    in let ModN y = square (ModN x) 
    in y 
이의 요점은 내가 위의 기능을 사용할 필요가있다

은 (square)는 그 특정의 인스턴스 인 유형으로는 인수가 필요합니다 타입 클래스. 새로운 유형을 정의하고 Num의 인스턴스로 만듭니다. 그러나 모듈로 산술을 올바르게 수행하려면이 함수의 일반적인 설계로 인해 호출에서 호출로 변경 될 수있는 모듈러 기반 n에 따라 달라집니다. square 함수가이 시간 (그리고 이번에 만) 작업을 수행하는 방법을 사용자 정의 할 수 있도록 일회성 콜백 (일종의 경우)으로 인스턴스 함수를 정의하고자합니다.

"closure variables"를 데이터 유형 자체에 직접 통합하는 것 (즉, 번호와 해당 데이터가 속하는 기준을 나타내는 ModN (x, n))이있을 수 있습니다. 연산은 인수에서이 정보를 추출 할 수 있습니다. 그러나 다음과 같은 몇 가지 문제가 있습니다. 1) 다중 인수 함수 (예 : (*))의 경우 런타임에 이러한 정보가 일치하는지 확인해야합니다. 그리고 2) 인스턴스는 클로져 변수에 의존하기를 원할 수도있는 인수가 0 인 "values"를 포함 할 수 있습니다. 그러나 인수가 없기 때문에 인수에서 인수를 추출 할 수 없습니다.

+2

아니요 로컬 인스턴스를 가질 수 없습니다. 모듈러 산술 Oleg Kiselyov와 CC Shan은 그들의 논문 "Implicit Configurations"(http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf)에서이 문제를 해결했습니다. 개인적으로 저는 이것을 피하고 모듈 기반의 새로운 유형, 즉 Z7, Z12를 간단하게 만듭니다. Conal Elliott는 대안 유형 클래스를 선택하기위한 또 다른 패턴을 가지고 있습니다. "Applicative Data-Driven Computation"의 CxMonoid 참조 - http://conal.net/papers/data-driven/paper.pdf –

+1

실제로 반사 패키지는 기본적으로 Oleg 논문의 패키지 버전. – ehird

+0

하스 켈의 현 상태에 관해서 : no. 인스턴스는 어디에서나 도달 할 수있는 곳으로 이동합니다. 미래의 하스켈에 대한 가능한 조정에 관해서는 어쩌면. typeclasses 대신 자신의 메커니즘을 사용하는 것에 관해서 : 예. –

답변

11

제안 된 확장 프로그램은 내 this previous answer에서 설명한 동일한 문제가 있습니다. 로컬 인스턴스를 사용하여 동일한 키 유형이지만 다른 Ord 인스턴스가 다른 두 개의 Map을 만들면 모든 불변량이 다운됩니다.

그러나, reflection 패키지는 이러한 ModN 유형을 정의 할 수 있습니다 : 당신은 Reifies 제약 조건 단일 인스턴스를 정의하고 reify와 특정 N의 인스턴스를 활성화합니다. (나는 implicit parameters도 이것을 가능하게 만들 것이라고 믿지만 그 확장은 거의 사용되지 않습니다.)

관련 문제