haskell 如何弃用一个特定的类型类示例?

roejwanj  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(102)

我尝试执行以下操作,但在编译源代码时经常遇到解析错误:

instance FromRow Job where
  {-# DEPRECATED fromRow "Please do not depend on the FromRow instance of the Job type. It does not handle optional features, such as job-results and job-workflows. Depending upon your scenario, use 'jobRowParserSimple' or 'jobRowParserWithWorkflow' directly." #-}
  fromRow = jobRowParserSimple

在Haskell中可以做到这一点吗?怎么做?

khbbv19g

khbbv19g1#

我无法理解你在寻找什么。
我只能提出一个变体:我们可以让GHC在使用示例时引发一个 error,除非示例的用户确认他们真的想启用已弃用的示例。
这不是一个理想的解决方案,但我找不到更接近目标的方法。
不管怎样,这是怎么做的。我们首先在库中定义一些样板类和示例:

{-# LANGUAGE DataKinds, TypeFamilies, UndecidableInstances #-}

import GHC.TypeError
   
class MakeError a

instance
   (TypeError (Text "Please do not depend on the FromRow instance of the Job type. It does not handle optional features, such as job-results and job-workflows. Depending upon your scenario, use 'jobRowParserSimple' or 'jobRowParserWithWorkflow' directly."))
   => MakeError Job

根据需要在这里添加更多示例,每个示例对应一个所需的弃用。
然后,仍然在库代码中,我们添加一个带有可重写示例的类,引用MakeError,这将生成错误消息。

class EnableDeprecated a

instance {-# OVERLAPPABLE #-} MakeError a => EnableDeprecated a

最后,仍然在库代码中,我们添加我们想要弃用的示例。这里我定义了一个虚拟类、类型和示例。

class FromRow a where
   fromRow :: a

data Job

-- Note the deprecation constraint.
instance EnableDeprecated Job => FromRow Job where
  fromRow = undefined

最后,在完成 library 代码之后,我们考虑 user 代码。下面是一个使用过时示例的虚拟测试。

test :: Job
test = fromRow

此用户代码将触发一个错误,显示提及弃用的错误消息。
如果用户想要禁用弃用,他们可以添加以下示例:

instance EnableDeprecated Job

现在不再出现错误。
由于许多原因,这种解决方案并不理想。这里的主要问题是我们依赖于重叠的示例,所以最后一个instance EnableDeprecated Job在任何地方都在作用域中是至关重要的,否则我们可能会得到弃用错误,即使示例在其他地方也是如此。请注意,这是一个 * 孤儿 * 示例,这使得重叠机制变得脆弱:程序员的负担是在任何地方都将这个示例保持在作用域上。

相关问题