3
{-# LANGUAGE GADTs #-}
module Main where
data CudaExpr x where
C :: x -> CudaExpr x
Add :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Sub :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Mul :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Div :: (Num x, Fractional x) => CudaExpr x -> CudaExpr x -> CudaExpr x
Eq :: (Eq x) => CudaExpr x -> CudaExpr x -> CudaExpr Bool
-- LessThan :: CudaExpr x -> CudaExpr x -> CudaExpr Bool
-- If :: CudaExpr Bool -> CudaExpr x -> CudaExpr x -> CudaExpr x
eval (C x) = x
eval (Add a b) = eval a + eval b
eval (Sub a b) = eval a - eval b
eval (Mul a b) = eval a * eval b
eval (Div a b) = eval a/eval b
eval (Eq a b) = eval a == eval b
-- eval (LessThan a b) = eval a < eval b
-- eval (If cond true false) = if eval cond then eval true else eval false
main :: IO()
main = print "Hello"
단조 제한이라고 보이지 않습니다. GHC docs에서EQ (GADT) 케이스에서 왜 유형 오류가 발생합니까?
* Could not deduce: x ~ Bool
from the context: (t ~ Bool, Eq x)
bound by a pattern with constructor:
Eq :: forall x. Eq x => CudaExpr x -> CudaExpr x -> CudaExpr Bool,
in an equation for `eval'
at app\Main.hs:23:7-12
`x' is a rigid type variable bound by
a pattern with constructor:
Eq :: forall x. Eq x => CudaExpr x -> CudaExpr x -> CudaExpr Bool,
in an equation for `eval'
at app\Main.hs:23:7
Expected type: CudaExpr x -> Bool
Actual type: CudaExpr t -> t
* In the first argument of `(==)', namely `eval a'
In the expression: eval a == eval b
In an equation for `eval': eval (Eq a b) = eval a == eval b
* Relevant bindings include
b :: CudaExpr x (bound at app\Main.hs:23:12)
a :: CudaExpr x (bound at app\Main.hs:23:10)
'eval'의 반환 유형은 무엇이라고 생각하십니까? 'eval (Eq (C 3) (C 3))'는'True :: Bool'을 반환해야하기 때문에'Num x => x'가 될 수 없습니다. 'eval (Add (C 3) (C 3))'은'6 :: Num x => x'를 반환해야하기 때문에 'Bool'이 될 수 없습니다. – chepner
음, 분명히 그것은 함수에 전달 된 CudaExpr의 구조에 의존해야합니다. 나는 왜 그것이 하나가 아니어야하는지 알지 못합니다. 위의 예제는 팬텀 형식을 사용하여 인코딩 할 수 있다는 것을 알고 있습니다. 그래서 여기에 문제를 설정 한 typeclass 제약이 있습니까? ... 아니, 모든 사례를 주석 처리하지만 'Eq'는 주석으로 처리하더라도 여전히 작동하지 않습니다. –
알았어, 알았다. 그것은 결국 monomorhism 제한과 같은 것이 었습니다. 형식 주석 'eval :: CudaExpr x -> x'을 추가하면 오류가 사라집니다. 힌트를 가져 주셔서 감사합니다. –