How to get variable name in haskell
Asked Answered
S

3

12

I came to haskell having some c background knowledge and wondering is there an analog to

#define print( a ) printf( "%s = %d\n", #a, a )

int a = 5;
print( a );

that should print

a = 5

?

Saleswoman answered 25/10, 2011 at 23:12 Comment(0)
V
22

Here's the TH solution augustss mentioned:

{-# LANGUAGE TemplateHaskell #-}
module Pr where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax

pr :: Name -> ExpQ
pr n = [| putStrLn ( $(lift (nameBase n ++ " = ")) ++ show $(varE n) ) |]

then in another module:

{-# LANGUAGE TemplateHaskell #-}
import Pr
a = "hello"
main = $(pr 'a)
Veroniqueverras answered 25/10, 2011 at 23:41 Comment(0)
P
19

You can use the same #define trick in Haskell if you turn on the CPP language extension. Or you can use Template Haskell to get the same effect.

But in pure Haskell it is impossible, because it violates the principle of alpha conversion, i.e., renaming bound variables (in a hygienic way) should not change the program semantics.

Photina answered 25/10, 2011 at 23:28 Comment(3)
Couldn't achieve this behaviour with {-# LANGUAGE CPP #-}. Seems GHC C preprocessor just ignores #.Saleswoman
Matvey, I think it is just that Haskell's printf doesn't take a tuple, but, in the first instance, just the format specification. Then it takes further arguments successively according to its interpretation of the format in question. "%s = %d\n" leaves room for two arguments. So you'd write e.g. printf "%s = %d\n" "five" 5 rather than printf( "%s = %d\n", "five" , 5). I paste something that works below; see what you can make of it.Hillman
By the way, a simple illustration of an extensive use of CPP to avoid boilerplate is here hackage.haskell.org/packages/archive/uu-parsinglib/2.7.3/doc/… Note the uncurrying in the message to the preprocessor: #define DEMO(p,i) demo "p" i pHillman
H
4
{-#LANGUAGE CPP#-}
import Text.Printf
#define print( a ) printf "%s = %d\n" (show a) a 

main = do  let a = (5 :: Int)
           print( a ) 



 $ ghci a.hs
 *Main> main
 5 = 5
Hillman answered 1/12, 2011 at 7:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.