Haskell 使用关联类型族时推断类型类约束
我知道。这样做的目的是对类的所有实例实施约束 但是我不知道如何在实例派生或函数声明中推断这些约束。例如,此代码无法进行类型检查:Haskell 使用关联类型族时推断类型类约束,haskell,types,typeclass,type-families,Haskell,Types,Typeclass,Type Families,我知道。这样做的目的是对类的所有实例实施约束 但是我不知道如何在实例派生或函数声明中推断这些约束。例如,此代码无法进行类型检查: {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} import Data.Proxy ( Proxy ) class Eq (FooT a) => Foo a where type FooT a :: * -- Can't infer it in an instance
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Proxy ( Proxy )
class Eq (FooT a) => Foo a where
type FooT a :: *
-- Can't infer it in an instance derivation
data CantInferEq a = CantInferEq (FooT a) deriving Eq
-- Also can't infer it in a function declaration.
-- The Proxy is there to avoid non-injectivity issues.
cantInferEq :: Proxy a -> FooT a -> FooT a -> Bool
cantInferEq _ x y = x == y
错误消息如下:
Test.hs:11:52: No instance for (Eq (FooT a)) …
arising from the first field of ‘CantInferEq’ (type ‘FooT a’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Eq (CantInferEq a))
Test.hs:16:23: No instance for (Eq (FooT a)) arising from a use of ‘==’ …
In the expression: x == y
In an equation for ‘cantInferEq’: cantInferEq _ x y = x == y
Compilation failed.
这是怎么回事?是否有一个解决方法来获得我想要的行为?问题的关键是,只要给我一个
脚a
,你就没有地方可以从Eq
实例字典中提取
解决方法是在您的typeclass要求中明确,从而有一个传递Eq
dict的地方:
{-# LANGUAGE StandaloneDeriving, UndecidableInstances #-}
data CantInferEq a = CantInferEq (FooT a)
deriving instance (Eq (FooT a)) => Eq (CantInferEq a)
cantInferEq :: (Eq (FooT a)) => Proxy a -> FooT a -> FooT a -> Bool
cantInferEq _ x y = x == y
或者,您可以通过将Eq(FooT a)
字典与CantInferEq
构造函数打包,避免使用undedicatableinstances
:
{-# LANGUAGE GADTs, StandaloneDeriving #-}
data CantInferEq a where
CantInferEq :: (Eq (FooT a)) => FooT a -> CantInferEq a
deriving instance Eq (CantInferEq a)