代码之家  ›  专栏  ›  技术社区  ›  Dan Burton

如何让GHC发出给定函数的警告?

  •  3
  • Dan Burton  · 技术社区  · 6 年前

    假设我决定在给定的代码基(包)中的任何地方都要使用自定义 getCurrentTimeMicroseconds 而不是 getCurrentTime . 有没有办法让GHC向我发出关于使用 获取当前时间 ,只在那个代码库中?(不适用于任何上游或下游。)

    另外一个问题,假设我想有选择地允许在使用站点(最好不是模块范围)使用带有显式注释的用法。这也是可能的吗?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Moss Prescott    6 年前

    这就是它的类型。用于时间的类型应反映要对其表示的值施加的约束。

    例如,您可以包装 UTCTime 像这样:

    newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
    
    microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
    microsecondsFromPicos = ...
    
    getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
    getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
    

    并且在包中的任何地方都使用新类型,您需要多次才能拥有此属性。

    如果你想对它严格,不要导出 UTCTimeMicroseconds 构造函数,因此获取这些值之一的唯一方法是使用 microsecondsFromPicos 执行您的要求。

    这使得任何误用都是一个错误,而不是警告,但在大多数情况下,这就是你想要的。

    当你想用的时候 统一时间 有了完整的分辨率,或者只是不关心,您可以像往常一样使用这种类型。在代码库中很容易找到发生这种情况的地方,因为它们是 只有 地点在哪里 统一时间 使用。

        2
  •  1
  •   jberryman    6 年前

    我现在想不出一种方法来做这件事,但我认为你能得到的最接近的是:

    • 创建新包 my-time 这取决于 time
    • 重新导出带有警告注释的填充函数,例如

      import qualified Data.Time as Time
      {-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
      getCurrentTime = Time.getCurrentTime
      
    • 依靠 我的时间 在你的包裹里

    显然,这并不能让你强制执行 进口 Data.Time.getCurrentTime 当您想要填充的代码在前奏曲或 base .