haskell - 如何派生具有类型族的记录的实例

标签 haskell type-families deriving

这是我正在尝试但无法编译的内容:

{-# 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/

相关文章:

haskell - 使用通用元组函数一次多次折叠

haskell - 枚举 Generic 实例的所有值时无限递归

haskell - 不在范围内 : type constructor or class ‘∼’

haskell - 通过 ReaderT 导出

haskell - Haskell 中的 groupByKey - 如何通过函数对列表中的项目进行分组?

unit-testing - 模拟 IO 操作 : getArgs and putStrLn

haskell - 约束的类型别名不与上下文共享相同的变量绑定(bind)行为

haskell - 如何为递归单例类型定义 NFData 实例?

haskell - 为什么没有 `-XDeriveApplicative`扩展名?

haskell - `DeriveAnyClass` 和空实例有什么区别?