这是我正在尝试但无法编译的内容:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
import Data.Text as T
import Data.Int (Int64)
type family Incoming validationResult baseType
type instance Incoming Validated baseType = baseType
type instance Incoming ValidationErrors baseType = Either [T.Text] baseType
data Validated
data ValidationErrors
data Tag = Tag {unTag :: T.Text} deriving (Eq, Show)
data NewTag f = NewTag
{
ntClientId :: Incoming f Int64
, ntTag :: Incoming f Tag
}
deriving instance (Show baseType) => Show (Incoming Validated baseType)
deriving instance (Show baseType) => Show (Incoming ValidationErrors baseType)
编译错误:
23 38 error error:
• Illegal type synonym family application in instance:
Incoming Validated baseType
• In the stand-alone deriving instance for
‘(Show baseType) => Show (Incoming Validated baseType)’ (intero)
24 38 error error:
• Illegal type synonym family application in instance:
Incoming ValidationErrors baseType
• In the stand-alone deriving instance for
‘(Show baseType) => Show (Incoming ValidationErrors baseType)’ (intero)
最佳答案
这里有两个问题。第一个是 GHC 告诉你的。基本上,您不能拥有依赖于类型族的实例(类型族可以存在,但前提是它获得的所有参数都是具体类型)。一旦您允许这样做,各种不好的事情就会开始发生,其中最重要的是您的类型系列的右侧可能会调用其他类型系列。
通常,可以通过将类型族应用程序移至约束来解决此类问题:
deriving instance (Show baseType, i ~ Incoming Validated baseType) => Show i
deriving instance (Show baseType, i ~ Incoming ValidationErrors baseType) => Show i
这样做实际上使第二个问题变得明显:你的实例头太笼统了。
也就是说,我不确定是否有什么需要修复的 - 只需摆脱派生行即可。您希望第一个可以归结为:在给定 Show basetype
约束的情况下派生一个 Show basetype
实例(这是完全没有意义的)。第二个同样毫无意义 - Either
已经有一个 Show
实例。
关于haskell - 如何派生具有类型族的记录的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41456841/