首页 文章

使用GHC Haskell进行编译时断言?

提问于
浏览
12

来自C,我通过使用模板元编程和/或 cpp(1) 来满足

例如,如果我想确保我的程序仅在 Int 至少具有某个 minBound / maxBound 范围时编译,或者,如果当前编译目标可以实现从 Int64Int 的无损失(如可逆)转换 . 这可能是GHC Haskell扩展的一部分吗?我的第一个猜测是使用TH . 是否还有其他可以利用的GHC设施?

2 回答

  • 9

    这是Anthony's example的通用和略微简化版本:

    {-# LANGUAGE TemplateHaskell #-}
    module StaticAssert (staticAssert) where
    
    import Control.Monad (unless)
    import Language.Haskell.TH (report)
    
    staticAssert cond mesg = do
        unless cond $ report True $ "Compile time assertion failed: " ++ mesg
        return [] -- No need to make a dummy declaration
    

    用法:

    {-# LANGUAGE TemplateHaskell #-}
    import StaticAssert
    
    $(staticAssert False "Not enough waffles")
    
  • 6

    使用TH来做到这一点并不算太糟糕 . 这是一个模块,它定义了所需的断言作为残留声明的一部分:

    {-# LANGUAGE TemplateHaskell #-}
    module CompileTimeWarning where
    import Control.Monad (unless)
    import Data.Int (Int64)
    import Language.Haskell.TH
    
    assertInt = let test = fromIntegral (maxBound::Int) == (maxBound::Int64)
                in do unless test $ report True "Int is not safe!"
                      n <- newName "assertion"
                      e <- fmap NormalB [|()|]
                      return $ [FunD n [Clause [] e []]]
    

    使用断言涉及顶级声明,该声明不用于断言以外的任何其他内容:

    {-# LANGUAGE TemplateHaskell #-}
    import CompileTimeWarning
    $(assertInt)
    

相关问题