4

いくつかの単純な2D図形を画面に描画するHaskellプログラムを作成しようとしていますが、各図形にカーソルを合わせると、図形が作成されたソースコードの行が出力されます。

これを行うために、寸法のパラメーターと行番号を示す最終パラメーターを使用して形状を作成できるようにしたいと思います。このようなもの:

rect1 = Shape(Rectangle 2 2 lineNumber)

これにより、幅2ピクセル、高さ2ピクセルの長方形が作成され、関数lineNumberを使用して、このコードが記述された行が格納されます。そのような関数はHaskellに存在しますか?作成するのは簡単ですか?

私はスタックオーバーフローを検索し、回答者がC++の__LINE__プラグマを使用して同様の効果を達成できることを示唆しているこの質問を見つけました。これはそれを実行するための最良の方法ですか、それとも純粋なHaskellでそれを行う方法はありますか?

4

1 に答える 1

6

これは、技術的にはさらに別のGHC拡張機能であるTemplate Haskellを使用して行うことができますが、おそらくCプリプロセッサよりも「純粋」です。

ここからコードが盗まれ、わずかに変更されました。

{-# LANGUAGE TemplateHaskell #-}

module WithLocation (withLocation) where
import Language.Haskell.TH

withLocation' :: String -> IO a -> IO a
withLocation' s f = do { putStrLn s ; f }

withLocation :: Q Exp
withLocation = withFileLine [| withLocation' |]

withFileLine :: Q Exp -> Q Exp
withFileLine f = do
    let loc = fileLine =<< location
    appE f loc

fileLine :: Loc -> Q Exp
fileLine loc = do
    let floc = formatLoc loc
    [| $(litE $ stringL floc) |]

formatLoc :: Loc -> String
formatLoc loc = let file = loc_filename loc
                    (line, col) = loc_start loc
                in concat [file, ":", show line, ":", show col]

(別のモジュールから)次のように使用します。

{-# LANGUAGE TemplateHaskell #-}

module Main where
import WithLocation

main = do
  $withLocation $ putStrLn "===oo0=Ü=0oo=== Kilroy was here"
于 2012-11-15T22:14:16.947 に答える