나는 다음과 같은 코드를 가지고 있고, 이 유형 검사를 실패에 나는 이것을 싶습니다제한된 제약 조건을 GADT와 함께 사용하려면 어떻게해야합니까?
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
import Control.Lens
data GADT e a where
One :: Greet e => String -> GADT e String
Two :: Increment e => Int -> GADT e Int
class Greet a where
_Greet :: Prism' a String
class Increment a where
_Increment :: Prism' a Int
instance Greet (Either String Int) where
_Greet = _Left
instance Increment (Either String Int) where
_Increment = _Right
run :: GADT e a -> Either String Int
run = go
where
go (One x) = review _Greet x
go (Two x) = review _Greet "Hello"
아이디어는 GADT의 각 항목은 내가 Prism
로 모델링하고있어 관련 오류를 가지고 있다는 것입니다 좀 더 큰 구조. 이 GADT를 "해석"할 때 e
에 대한 구체 유형을 제공하며이 유형은 모두 Prism
에 대한 인스턴스를 갖습니다. 그러나 각 개별 사례에 대해 생성자의 관련 컨텍스트에서 선언되지 않은 인스턴스를 사용할 수 있기를 원하지 않습니다.
Two
에서 패턴 일치가 발생하면 Increment e
만 사용할 수 있지만 Greet
을 사용하고 있기 때문에 위의 코드는 오류가되어야합니다. 이유가 무엇인지 알 수 있습니다. Either String Int
에 Greet
에 대한 인스턴스가 있으므로 모든 것이 체크 아웃됩니다.
이 문제를 해결하는 가장 좋은 방법은 무엇인지 모르겠습니다. 어쩌면 Data.Constraint
의 함부로 사용하거나 더 높은 순위 유형의 트릭이있을 수 있습니다.
아이디어가 있으십니까?
확장하려면 Ed가 중요합니다. 중요한 부분은'run'의 정의가 아닌 * calling * run의 시점에서'e'를 제공하는 것입니다. – ocharles