Debugging Haskell: LFG, AVM → DAG
A few days ago I had to do some debugging in Haskell while writing a function to draw directed acyclic graphs of attribute value matrices from LFG F-structures. UnsafePerformIO was great help there. I did most of this during a machine translation lecture given by Kurt Eberle of lingenio.
Here are the debugging functions:
deb1 :: Show a ⇒ a → a
deb1 a = unsafePerformIO (print a >> return a)
deb2 :: Show a ⇒ String → a → a
deb2 msg a = unsafePerformIO (putStrLn (((msg ++) . show) a) >> return a)
deb3 :: (Show a, Show b) ⇒ (a → Bool) → b → a → a
deb3 p b a = unsafePerformIO $ esc p b a
where
esc p b a | p a = putStr ((show b) ++ (show a)) >> return a
| otherwise = return a
cond = (== "^OBL")
dobj = deb3 cond
And here is how I used them in context:
core :: Integer → String → [(Integer,String)] → AVM → (String,[(Integer,String)],Integer)
core i s ls (M att (A val)) = (s ++ x i ++ " [label=\"" ++ dobj s att ++ "\"];\n",(i,val):ls,i)
core i s ls (M att (C mms)) = let (xs,xls,xi) = add i i s ls att mms in
(s ++ x i ++ " [label=\"" ++ att ++ "\"];\n" ++ xs,xls,xi)
where
add f i s ls att [] = ([],[],i)
add f i s ls att (m:ms) = (cs ++ rs,cls ++ rls,ri)
where
(cs,cls,ci) = core ni sm ls m
(rs,rls,ri) = add f ci [] ls att ms
sm = x f ++ " -> "
ni = i + 1
I know core pretty much sucks in many ways o_O!! Still trying to figure out how I could keep such things maintainable in Haskell... (I will have a look at the FGL sometime soon.)
It was very easy to use type classes and unicode infix functions to achieve a really pretty syntax to represent F-structures though ^o^:
s1 :: AVM
s1 = void ≈
[pred ≈ "antworten<(^SUBJ)(^OBL)>",
subj ≈ [pred ≈ pro,
num ≈ sg,
cas ≈ nom ],
obl ≈ [pred ≈ "auf<^OBJ>",
obj ≈ [pred ≈ "Brief",
num ≈ sg,
cas ≈ acc] ],
tense ≈ present ]
Machine translation is the last lecture before sommer holidays *^o^*! I will have more time to work on Corsis again.
Comments
putTraceMsg msg = hPutStrLn stderr msg
trace string expr = unsafePerformIO $ do
putTraceMsg string
return expr
So no need to redefine it :-)