寻找在Haskell的函数的行号(Finding the line number of a func

2019-08-02 18:18发布

我想创建一个Haskell程序,得出了一些简单的2D形状的屏幕,但是当你将鼠标悬停在每个形状,它打印在其中创建形状的源代码行。

为了做到这一点,我希望能够为他们的尺寸参数,指示行号的最终参数创建形状。 事情是这样的:

rect1 = Shape(Rectangle 2 2 lineNumber)

这将产生宽度为2个像素,高度2个像素的矩形,并使用一个函数行号来存储这段代码被写就行了。 请问这样的功能在Haskell存在吗? 它是简单的创建一个?

我已经搜索堆栈溢出,发现这个问题 ,其中回答者表明从C ++的__LINE__编译指示可用于实现类似的效果。 这是去它的最好办法还是有办法做到这一点在纯哈斯克尔?

Answer 1:

您可以使用模板哈斯克尔,这在技术上是另一个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"


Answer 2:

纯Haskell是不知道有关源代码级别的细节。 最佳的解决方案仍然是预处理一个Haskell源文件与外部预处理器中嵌入该信息,这是关注的自然分离。

这样的特征是动态编程系统,如Lisp,其中码处理和执行阶段在时间交织的有意义得多。 但据我所知,即使Common Lisp的不具有这样的特征,而EmacsLisp不(仅仅是因为它的应用领域是文本编辑器 ,而不是因为它的创作者已经决定如此)。



文章来源: Finding the line number of a function in Haskell