我正在尝试创建一个Haskell程序,该程序将一些简单的2D形状绘制到屏幕上,但是当您将鼠标悬停在每个形状上时,它会打印创建形状的源代码行。
为了做到这一点,我希望能够创建带有尺寸参数和指示行号的最终参数的形状。像这样:
rect1 = Shape(Rectangle 2 2 lineNumber)
这将创建一个宽 2 像素、高 2 像素的矩形,并使用函数 lineNumber 来存储编写这段代码的行。哈斯克尔中存在这样的函数吗?创建一个简单吗?
我搜索了堆栈溢出,发现了这个问题,回答者建议使用C++的__LINE__编译指示来实现类似的效果。这是最好的方法,还是有办法在纯粹的哈斯克尔中做到这一点?
你可以用 Template Haskell 来做到这一点,它在技术上是另一个 GHC 扩展,但可能在某种程度上比 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"