需要灵活的实例?
我想为它的C表示写一个Haskell类型的Convertible实例
它看起来像这样:
instance Convertible Variable (IO (Ptr ())) where
现在GHC抱怨说:
 Illegal instance declaration for `Convertible
                                    Variable (IO (Ptr ()))'
  (All instance types must be of the form (T a1 ... an)
   where a1 ... an are *distinct type variables*,
   and each type variable appears at most once in the instance head.
   Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Convertible Variable (IO (Ptr ()))'
如果你的实例声明中有空闲类型,我认为需要灵活实例,但事实并非如此。 添加正确的编译指示时,我可以编译它,但任何人都可以解释为什么我需要这个?
是的,你需要灵活的实例。 没有它,你所有的类型实例都必须看起来像
instance Foo (Maybe a) where
instance Foo (IO a)    where
instance Foo (Either a b) where
  如果你想要做的比其他任何事情TypeConstructor a1 a2 a3 ... (和a ■找是类型变量),比您需要灵活的实例。  但它是最常用的语言扩展之一,不要使用它。 
  在这种情况下,您通常可以避免使用FlexibleInstances 。  有两种一般方法: 
使用辅助类
instance ConvIO a => Convertible Variable (IO a) where
  method = methodIO
class ConvIO p where
  methodIO :: ...
  -- similar to the signature for the Convertible method,
  -- but with Variable and IO baked in
instance ConvIOPtr u => ConvIO (Ptr u) where
   methodIO = methodIOPtr
class ConvIOPtr u where
   methodIOPtr :: ...
instance ConvIOPtr () where ...
当您需要由相同的构造函数执行的多个实例时,此方法可以很好地工作。
使用相等约束
  打开GADTs或TypeFamilies并写入 
instance a ~ Ptr () => Convertible Variable (IO a) where ...
  这种方法对类型推断有帮助,但只有当你只需要一个以IO为首的实例时才有意义。 
你可以混合搭配
  您可以使用辅助类来通过IO ,然后使用相等约束来通过Ptr 。 
instance u ~ () => ConvIO (Ptr u) where ...
  或者你可以使用一个相等约束来通过IO和一个辅助类来通过Ptr : 
instance (a ~ Ptr u, ConvIOPtr u) => Convertible Variable (IO a)
这些不起作用
  如果你需要一个参数是一个类型变量的实例,那么你真的无法避免使用FlexibleInstances 。  您可能可以使用新类型解决问题,但不值得麻烦。 
