Haskell 如何创建独立派生实例

Haskell 如何创建独立派生实例,haskell,derived-instances,Haskell,Derived Instances,给定以下代码 {-# LANGUAGE StandaloneDeriving #-} type Date = Int data Decision a = Decision a deriving (Show) data InProgress a = InProgress {progress :: a, decision :: Decision a } deriving (Show) data Finished a = Finished {finished :: a, initial ::

给定以下代码

{-# LANGUAGE StandaloneDeriving  #-}

type Date = Int
data Decision a = Decision a deriving (Show)  

data InProgress a = InProgress {progress :: a, decision :: Decision a } deriving (Show)
data Finished a = Finished {finished :: a, initial :: a, timestamp :: Date } deriving (Show)  

data LineItem a = LineItem {article :: a String, amount :: a Float, units :: a Int } deriving (Show)  
我得到以下错误

source_file.hs:11:96:
    No instance for (Show (a Float))
    arising from the second field of ‘LineItem’ (type ‘a Float’)
    Possible fix:
    use a standalone 'deriving instance' declaration,
        so you can specify the instance context yourself
    When deriving the instance for (Show (LineItem a))
我尝试了一些类似下面这样的变化,但我无法运行它

deriving instance Show a => Show (InProgress Float)
我怎样才能解决这个问题?(请解释一下)

编辑

好的,我有办法了

deriving instance Show (LineItem InProgress)
我会做我想做的。我还是不明白为什么不是呢

deriving instance Show a => Show (LineItem (InProgress a))

a
行项目a
不是类型,即它没有种类
*
。 相反,它有种类
*->*

这意味着
a
将被类型构造函数替换。例如,
LineItem可能
很好,但是
LineItem(可能是Int)
不是

最通用的
Show
实例如下

deriving instance (Show (a String), Show (a Int), Show (a Float)) 
                  => Show (LineItem a)
但在那里,上下文涉及比头部更复杂的类型。这当然需要打开
不可判定实例
,可能还需要一些其他扩展

请注意,由于此实例不会将头部“简化”为更小的约束,因此有可能通过添加更多“坏”实例,使编译器永远循环。实际上,这种情况很少发生,我也不会太担心

如果您知道
a
在后续使用中只有有限数量的案例,您可以逐个列出它们,为每个案例提供一个实例,就像您在编辑中所做的那样

deriving instance Show (LineItem TyCon1)
...
deriving instance Show (LineItem TyConN)