我正在寻找一种安全的方法来为数据类型生成实例其中的字段没有派生类,但此类字段具有通用实例。
我认为使用QuickCheck进行测试非常流行,因为每种类型都应具有任意性。没有人愿意在生产中包含任意实例,但是否则,派生测试模块中的任意内容会发出孤立警告。
我可以在测试模块中为用户定义新类型,但是我不能对名称类型进行相同的操作。它在用户内部是硬编码的。
我了解孤立实例的问题。它们可以重叠,但是在这里,我希望GHC在递归派生UserAr的过程中派生Name的隐藏的Arbitrary实例。这样的Name任意实例应在UserAr的Arbitrary中,就像我手动编写的一样。我认为从技术上讲,至少通过Template Haskell,它必须是可行的。因此,我要求提供详细信息。
-- prod
import GHC.Generics
newtype Name = Name String deriving (Show, Generic)
data User = User Name deriving (Show, Generic)
-- test
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype UserAr = UserAr User deriving (Show, Arbitrary)
Haskell中没有隐藏实例这样的东西。具有不能在模块外部使用的实例的唯一方法是隐藏其所在的整个类型。为此,您需要为该类型制作一个newtype
包装器,并仅导出不包含该实例的包装器。然后,您可以使用GeneralizedNewtypeDeriving
和/或DerivingVia
来获取要返回的其他实例。