0
데이터 형식에 '숨겨진'(유추 된) 형식과 구체적인 값이 있습니다. 이제는이 두 가지를 변경하는 함수를 구현하려고 시도하지만 GHC를 통과시키지 못합니다.변형 매개 변수화 된 형식 (유추 된 매개 변수 사용)
data T tag val = T val
data A = A
data B = B
mkIntVal :: T a b -> T Int b
mkIntVal (T x) = T x
mkCharVal :: T a b -> T Char b
mkCharVal (T x) = T x
convert :: T Int a -> T Char b
convert (T A) = mkCharVal $ T B
convert (T B) = mkCharVal $ T A
가 생산하는 오류가 이것이다 :
내 샘플 코드는 이것이다이 작품을 만들기 위해해야할 것에
test.hs:13:12:
Couldn't match type `A' with `B'
In the pattern: A
In the pattern: T A
In an equation for `convert': convert (T A) = mkCharVal $ T B
test.hs:13:17:
Couldn't match type `B' with `A'
Expected type: T Char b
Actual type: T Char B
In the expression: mkCharVal $ T B
In an equation for `convert': convert (T A) = mkCharVal $ T B
? 데이터 구조를 변경해야합니까?
내가 다형성 데이터 유형 작업 할 Don Stewart
의 솔루션을 확장하기 위해 노력하고
편집 할 수 있습니다.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
data C a = C a deriving Show
class Convertable inVal outVal outTag | outVal -> outTag where
convert :: T Int inVal -> T outTag outVal
instance Convertable A B Char where
convert (T A) = mkCharVal $ T B
instance Convertable B A Char where
convert (T B) = mkCharVal $ T A
instance Convertable a b Char => Convertable (C a) (C (T Char b)) Char where
convert (T (C val)) = mkCharVal $ T (C (convert val)) -- line 29
그러나 그것은 나에게 또 다른 오류 메시지가 있습니다 : 나는 인스턴스 정의와 주위를 연주했지만 가장 유망한가 생각 해낸 찾고 이것이다
test.hs:29:57:
Could not deduce (a ~ T Int inVal0)
from the context (Convertable a b Char)
bound by the instance declaration at test.hs:28:10-70
`a' is a rigid type variable bound by
the instance declaration at test.hs:28:22
In the first argument of `convert', namely `val'
In the first argument of `C', namely `(convert val)'
In the first argument of `T', namely `(C (convert val))'
돈은 그것이 있어야 말했듯을 가능한 구현 방법에 관심이 있습니다.
훨씬 더 '재생'후 솔루션
나는 마지막으로 작동 뭔가를 내놓았다. 이게 너에게 잘 보이니?
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
data T tag val = T val deriving Show
data A = A deriving Show
data B = B deriving Show
data C a = C a deriving Show
class Convertable inTag inVal outTag outVal | inTag -> outTag, inVal -> outVal
where
convert :: T inTag inVal -> T outTag outVal
instance Convertable Int A Char B where
convert (T A) = T B
instance Convertable Int B Char A where
convert (T B) = T A
instance (Convertable Int (T Int a) Char (T Char b), Convertable Int a Char b)
=> Convertable Int (C (T Int a)) Char (C (T Char b)) where
convert (T (C x)) = T (C (convert x))
instance Convertable Int (C (T Int A)) Char (C (T Char B)) where
convert (T (C x)) = T (C (convert x))
instance Convertable Int (C (T Int B)) Char (C (T Char A)) where
convert (T (C x)) = T (C (convert x))
사용법 :
*Main> convert $ mkIntVal $ T $ C $ mkIntVal $ T A
T (C (T B))
*Main> :t it
it :: T Char (C (T Char B))
이제 내 시도가 잘못되었다는 것을 이해합니다. 나중에이 솔루션을 다형성 결과 유형으로 확장하거나 "일반"유형으로 제한 할 수 있습니까? 인스턴스 정의에 넣을 구체적인 값이 없기 때문에'convert (T (C val)) = mkCharVal $ T (C (convert val))와 같은 함수를 어떻게 만들지 모르겠다. ' –
가능해야합니다. 시도 해봐! –