代码之家  ›  专栏  ›  技术社区  ›  bbarker

是否可以为我的类型类Y提供某些类型类X的默认实例?

  •  3
  • bbarker  · 技术社区  · 6 年前

    例如,假设我正在实现类型类 Y 我想要所有的实例 a 属于 X a 对于其他类型的类 X . 起初,我试图通过写作来做到这一点 instance Y a => X a where ... Haskell Constraint is no smaller than the instance head ).但是,与另一个问题中描述的可能有多个类型类约束的更一般的情况不同,我的情况中只有一个类约束,因此我认为可能有一种方法可以在类定义级别实现这一点,可能使用Haskell语言扩展。

    X 实际上是 Ord . 包装 有人 newtype 防止直接使用 作战需求

    2 回复  |  直到 4 年前
        1
  •  9
  •   Alec    6 年前

    这里通常的技巧是定义一个 newtype 使用所需的实例进行包装。看见 WrappedMonoid 举个例子。就你而言:

    newtype WrappedY a = WrapY { unwrapY :: a }
    
    instance Y a => X (WrappedY a) where 
      -- your default implementation here
    

    然后,是一个具有 Y 可以导出其实例 X DerivingVia 扩大

    {-# LANGUAGE DerivingVia #-}
    
    data SomeType = ...
      deriving X via WrappedY SomeType
    
    instance Y SomeType where
      -- your implementation here
    
        2
  •  5
  •   typesanitizer    6 年前

    如果用户有GHC 8.6+可用,Alec答案中的newtype wrapper+DerivingVia建议可以很好地工作( DerivingVia 是一个相当新的扩展)。如果这不是一个选项,您可以做如下操作-

    1. implXViaY 它为 X Y . 例如,这有时是通过应用程序实例以 (<*>) = ap ap 是基于 >>= fmap = liftA 哪里 liftA (<*>)

    2. 提供一个模板Haskell函数,在type类有很多方法的情况下自动使用默认定义(这基本上是1的扩展)。大概是 makeXviaY ''MyType 对于用户。这需要客户端启用TemplateHaskell。

    推荐文章