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

Anonymous said…
Probably you should use Debug.Trace.trace, which is implemented as,

putTraceMsg msg = hPutStrLn stderr msg

trace string expr = unsafePerformIO $ do
putTraceMsg string
return expr

So no need to redefine it :-)

Popular posts from this blog

Levenshtein Distance Algorithm: Fastest Implementation in C#

WordSmith Tools 5.0, Tenka Text in China

Mono 1.2.5 binaries for Solaris 10/x86