在Haskell中查找函数的行号 [英] Finding the line number of a function in Haskell

查看:232
本文介绍了在Haskell中查找函数的行号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个Haskell程序,它绘制一些简单的2d形状到屏幕上,但当你悬停在每个形状,它打印的源代码行的形状创建。



为了做到这一点,我想要能够创建带有参数的形状的尺寸和一个表示行号的最终参数。像这样:

  rect1 = Shape(Rectangle 2 2 lineNumber)
pre>

这将创建一个宽度为2像素,高度为2像素的矩形,并使用一个函数lineNumber来存储这段代码所写的行。 Haskell中是否存在这样的函数?是否很容易创建一个?



我搜索了堆栈溢出,发现这个问题,回答者建议使用C ++中的__LINE__ pragma来实现类似的效果。

解决方案

你可以这样做,这是最好的方法去做它或者有一个方法来做它在纯Haskell?与模板Haskell,这是技术上另一个GHC扩展,但可能是比C预处理器更纯。



代码从在这里,稍作修改。

  { - #LANGUAGE TemplateHaskell# - } 

模块WithLocation(withLocation)其中
import语言。 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 =<<位置
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# - } 

模块主要其中
import WithLocation

main = do
$ withLocation $ putStrLn=== oo0 =Ü= 0oo === Kilroy在这里


I am trying to create a Haskell program which draws some simple 2d shapes to screen, but when you hover over each shape, it prints the line of source code where the shape was created.

In order to do this I would like to be able to create shapes with parameters for their dimensions and a final parameter which indicates the line number. Something like this:

rect1 = Shape(Rectangle 2 2 lineNumber)

This would create a rectangle of width 2 pixels, height 2 pixels, and use a function lineNumber to store the line this piece of code was written on. Does such a function exist in Haskell? Is it simple to create one?

I have searched stack overflow and found this question where the answerer suggests that the __LINE__ pragma from C++ can be used to achieve a similar effect. Is this the best way to go about it or is there a way to do it in pure Haskell?

解决方案

You can do this with Template Haskell, which is technically yet another GHC extension, but is probably somehow more "pure" than C preprocessor.

Code stolen from here and modified slightly.

{-# 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]

Use it like this (from another module):

{-# LANGUAGE TemplateHaskell #-}

module Main where
import WithLocation

main = do
  $withLocation $ putStrLn "===oo0=Ü=0oo=== Kilroy was here"

这篇关于在Haskell中查找函数的行号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆