This trick is by EvilTerran from #haskell freenode IRC channel.
A quick and dirty way to debug Haskell code is to use trace
function from Debug.Trace
module.
For example,
f (trace ("arg1: " ++ show arg1) arg1) arg2
would print
arg1: <actual value of arg1>
Usung Template Haskell, above code can be shortened.
> {-# LANGUAGE TemplateHaskell #-}
This means this code uses TemplateHaskell extension.
> module Trace where
Let's call the module Trace.
> import Language.Haskell.TH
> import Debug.Trace (trace)
And, import some modules.
> t name = [| trace ($(litE . StringL $ nameBase name)
> ++ ": " ++ show $(varE name)) $(varE name) |]
Then, define the macro t
that can be called as:
$(t 'varName)
And it'll be expanded to:
trace ("varName" ++ ": " ++ show varName) varName
Let's actually use Trace.t
in Main module.
> {-# LANGUAGE TemplateHaskell #-}
Main module also needs to use TemplateHaskell extension because it'll include macro call like $(t 'a)
.
> module Main where
> import Trace (t)
> import Debug.Trace (trace)
> main = do
> let a = 2
> let bravo = 40
> putStrLn $ show ((trace ("a: " ++ show a) a) + bravo)
compare this with
> putStrLn $ show ($(t 'bravo) + $(t 'a))
> return ()
Shorter.
Now, I need vim keyboard shortcut that'll replace the word under cursor with $(t 'wordUnderCuror)
. And, another keyboard shortcut that'll turn $(t 'word)
into word
.
Edit: Alok commented with vim function below:
" word <===> $(t 'word)
" by Alok
function! ToggleTrace()
call searchpos('\|)')
let b = searchpos('\<', 'b')
let s = searchpos("\$(t '", 'b')
if s[0] == b[0] && b[1] - s[1] == len("$(t '")
" remove trace
norm df'f)x
else
" add trace
call insert (b, 0, 0)
call add (b, 0)
call setpos('.', b)
let @z = "$(t '"
norm "zP
let @z = ")"
norm f "zP
endif
endfunction
nmap <leader>t :call ToggleTrace()<cr>
Thank you Alok.