Simple debugging in Haskell

前端 未结 5 2124
醉话见心
醉话见心 2021-02-07 19:04

I am new to Haskell. Previously I have programmed in Python and Java. When I am debugging some code I have a habit of littering it with print statements in the midd

5条回答
  •  死守一世寂寞
    2021-02-07 19:59

    I was able to create a dual personality IO / ST monad typeclass, which will print debug statements when a monadic computation is typed as IO, them when it's typed as ST. Demonstration and code here: Haskell -- dual personality IO / ST monad? .

    Of course Debug.Trace is more of a swiss army knife, especially when wrapped with a useful special case,

    trace2 :: Show a => [Char] -> a -> a
    trace2 name x = trace (name ++ ": " ++ show x) x
    

    which can be used like (trace2 "first arg" 3) + 4

    edit

    You can make this even fancier if you want source locations

    {-# LANGUAGE TemplateHaskell #-}
    import Language.Haskell.TH
    import Language.Haskell.TH.Syntax as TH
    import Debug.Trace
    
    withLocation :: Q Exp -> Q Exp
    withLocation f = do
        let error = locationString =<< location
        appE f error
        where
            locationString :: Loc -> Q Exp
            locationString loc = do
                litE $ stringL $ formatLoc loc
    
    formatLoc :: Loc -> String
    formatLoc loc = let file = loc_filename loc
                        (line, col) = loc_start loc
                    in concat [file, ":", show line, ":", show col]
    
    trace3' (loc :: String) msg x =
        trace2 ('[' : loc ++ "] " ++ msg) x
    trace3 = withLocation [| trace3' |]
    

    then, in a separate file [from the definition above], you can write

    {-# LANGUAGE TemplateHaskell #-}
    tr3 x = $trace3 "hello" x
    

    and test it out

    > tr3 4
    [MyFile.hs:2:9] hello: 4
    

提交回复
热议问题