13

C++ から来た私は、単純な形式のコンパイル時アサーションを作成することに慣れていました。テンプレート メタを使用していくつかの単純な条件 (単純な代数式など) が満たされない場合、コンパイル中に警告またはエラーを発生させることができました。 -プログラミングおよび/またはcpp(1)

Intたとえば、少なくとも特定のminBound/範囲がある場合にのみプログラムがコンパイルされるようにしたい場合、または現在のコンパイルターゲットでからへmaxBoundの損失のない (可逆的な) 変換が可能である場合。GHC Haskell拡張機能でこれは可能ですか? 私の最初の推測は、THを使用することでした。この目的のために悪用できる GHC 施設は他にありますか?Int64Int

4

2 に答える 2

11

Anthony の例を一般化して少し簡略化したバージョンを次に示します。

{-# 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")
于 2011-07-11T18:45:12.333 に答える
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)
于 2011-07-11T17:55:15.730 に答える