【问题标题】:Wrap a type in newtype在 newtype 中包装一个类型
【发布时间】:2020-06-12 19:03:17
【问题描述】:

在下面的代码中我收到警告Orphan instance: instance (MonadIO m, Monad m) => GenerateUUID m

instance (MonadIO m, Monad m) => GenerateUUID m where
  generateUUID = liftIO nextRandom

根据它的解决方案是

        move the instance declaration to the module of the class or of the type, or
        wrap the type with a newtype and declare the instance on the new type.

(或禁用警告帽子互联网也建议)

我的问题是我找不到如何用新类型包装类型?

【问题讨论】:

  • 看看 Learn You A Haskell for Great Good,了解有关 Haskell 的一些基础知识。
  • GenerateUUID 是在哪里定义的?
  • 我很确定你不应该像这样定义一个实例。如果您确实定义了一个实例 GenerateUUID m,那么这将最终成为 any 类型 m 的实例,因此您将无法再定义任何 GenerateUUID 实例,因为它们将与您的最大通用 m 实例重叠。 (由于 GHC 的实例解析是如何工作的,即使您给出约束 (MonadIO m, Monad m) 也是如此。)
  • 看来generateUUID 应该是顶级定义,而不是类型类的方法。您是否创建了这个 GenerateUUID 类型类?还是来自图书馆?

标签: haskell ghc deriving derivingvia


【解决方案1】:

你可以像这样定义一个新类型的包装器:

newtype Foo m a = Foo { unFoo :: m a }

如果我们还想说“我希望 Foo 拥有与 m 相同的 FunctorMonadApplicative... 实例,唯一的区别是方法使用 @ 987654329@ 代替 m a" 我们可以使用 -XDerivingVia 扩展:

{-# LANGUAGE DerivingVia #-}

newtype Foo m a = Foo { unFoo :: m a } 
                deriving (Functor,Applicative,Monad,MonadIO,GenerateUUID) via m

只要编译器抱怨缺少Foo 的实例,请将其添加到deriving 子句中。


略有改进。假设我们还想“继承”SemigroupMonoid 实例。例如:IO ()Monoid,所以我们可能希望 Foo IO () 也是 Monoid。我们需要一个单独的deriving 子句:

newtype Foo m a = Foo { unFoo :: m a } 
                deriving (Functor,Applicative,Monad,MonadIO) via m
                deriving (Semigroup,Monoid) via (m a)

为什么是单独的子句?因为类型类有不同的种类。 Functor 有一种(Type -> Type) -> Constraint,我们正在声明Foo m 的实例,它有一种Type -> Type

同时,Semigroup 具有种类 Type -> Constraint,我们正在声明 Foo m a 的实例,即具有种类 Type 的“完全应用”类型构造函数。

【讨论】:

  • “继承”包装类型的实例也可以使用GeneralizedNewtypeDeriving 扩展或deriving newtype 策略downloads.haskell.org/ghc/latest/docs/html/users_guide/… 来完成,但我更喜欢DerivingVia,因为它更明确且更通用.
  • 我刚刚注意到,即使使用包装类型,当我将“实例”移动到与 Foo 不同的填充时,警告仍然存在...
  • @majkrzak 为什么需要这样做?
猜你喜欢
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 2011-03-04
  • 2016-12-29
  • 2015-07-21
  • 1970-01-01
相关资源
最近更新 更多