2017-12-06 16 views
2

나는 하스켈에서 다음을 예로 듭니다.하스켈에서 GADT 표현식 유형을 동적으로 만들 수 없습니다.

{-# LANGUAGE GADTs #-} 
import Data.Dynamic  

data Expr a where 
    Lift :: (Show a) => a -> Expr a --Lift some type into Expr 
    Lam :: (Expr a -> Expr b) -> Expr (a -> b) 
    Const :: Expr a -> Expr b -> Expr a 

다음에서 동적을 만들려고 할 때 수정 방법을 잘 모르겠다는 오류가 발생합니다.

--This is the code 
toDyn $ (Lam (Const (Lift 1))) 
-- This is the error 
-- • No instance for (Typeable b0) arising from a use of ‘toDyn’ 
-- • In the expression: toDyn (Lam (Const (Lift 1))) 
-- In an equation for ‘it’: it = toDyn (Lam (Const (Lift 1))) 

거기에 방법이 있습니까? 다른 생성자는 모두 잘 작동합니다 (내 실제 프로그램에는 100 개가 넘습니다!)하지만 Const가 정말 저에게 문제가됩니다!

+0

'(Lam ...) '에 특정 유형을 제공해야합니다. 그렇지 않으면 너무 일반적이어서 다형성 유형 만 지정할 수 있습니다. 기본적으로'Const' 응용 프로그램에서'b'가 무엇인지 선택해야합니다. – chi

답변

1

Const에 대한 두 번째 인수의 유형, 즉 버려지는 것이 Typeable 일 필요가 있습니다. 그러나 이것은 유형이 가능한 제약이없는 완전히 일반적인 유형 변수입니다. 당신은

toDyn (Const (Lift 1) :: Expr Int -> Expr Int) 

또는

toDyn (Lam (Const (Lift 1) :: Expr Int -> Expr Int)) 

모두 작업 같은 것을 작성하는 경우.

+0

일반 변수에 유형 지정 가능한 제약 조건을 부여 할 수있는 방법이 있습니까? ''데이터 익스프레션 '을 시도했는데 행운이없이 Const :: (Typeable a, Typeable b) => Expr a -> Expr b -> Expr a'입니다. 나는 심지어 Expr을 위해 autoderiving Typeable을 시도했다. – Donovan

+0

@Donovan 나는 그걸 가지고 놀고 있었지만,'Typeable'은 그런 식으로 작동하지 않는다고 생각합니다 - 타입 변수가 실존 적이라는 것이 문제라고 생각합니다. –

+0

@Donovan 결국에는 Typeable 인스턴스에 대한 특정 유형이 있어야합니다. 그러나 실존 적 목적 때문에 결코 제공 될 수 없습니다. 적어도 나는 그렇게 생각합니다. 'toDyn (\ a -> a)'와 같은 다형 함수에서 직접 toDyn을 시도하면 비슷한 오류가 발생합니다. 반면에'toDyn (\ a -> a + a)'는'Num' 제약 조건의 기본값 때문에 ok입니다. –