2017-09-04 68 views
1

我想用派生的实例是这样的:Derived实例在Haskell

data Test3D = forall a. (Show a, Eq a, Typeable a, Generic a) 
       => Test3D { testDt :: String 
          , testPrm :: a 
          } 
    deriving (Show, Eq, Typeable, Generic) 

instance Binary (Test3D) 
$(deriveJSON defaultOptions ''Test3D) 

但我从GHC收到:

• Can't make a derived instance of ‘Show Test3D’: 
     Constructor ‘Test3D’ has existentials or constraints in its type 
     Possible fix: use a standalone deriving declaration instead 
• In the data declaration for ‘Test3D’ 

这种方式是我的项目非常方便。我找不到解决方案。

是否有任何使用这种数据的派生实例?

+1

你将如何自己写实例?即使写出类型签名也很困难,如果你想显示任何有关'testPrm'的信息。如果你不知道如何去做,那么GHC不能自动为你做。另一方面,如果你不关心显示'testPrm',那么这个实例很容易用手写,你不需要派生它。 – amalloy

+1

这涉及到为每个'Generic'写一个'Binary'实例。它看起来是一个相当复杂的任务。我认为我们不能切实希望自动推演机制能够为我们解决这个问题。也许我们可以手动编写一个更简单的实例,如果我们使用'Binary a'而不是'Generic a'? – chi

+0

也许我没有正确实施我的想法。我只想要一些类型的数据,而这些数据又包含一个未知类型的字段。但是字段类型通过类型类来满足一定的要求。它们都应该是(显示一个,等式a,可键入a,泛型...)。 – QSpider

回答

5

是否有任何方式使用派生实例的这种数据?

是的。不要什么GHC建议,使独立派生条款:

{-# LANGUAGE StandaloneDeriving, ExistentialQuantification #-} 

data Test3D = forall a. (Show a) 
       => Test3D { testDt :: String 
          , testPrm :: a 
          } 

deriving instance Show Test3D 

什么你不能做的就是得到一个Eq实例,因为不同的价值观实际上可能包含不同类型,它是唯一可能与动态铸比较这些通过Typeable破解。