Question

I'm writing some parse code over a tree. (Namely an Stanford nlp dependency tree)

Basically I have a function like this:

m :: DepTree -> Logic
m (w, [E "nsubj" nsubj, E "dobj" dobj]) = ...
m (w, [E "nsubj" nsubj, E "prep" prep]) = ...
m (w, [E "nsubj" nsubj]) = ...
m (_, []) = error "No rules apply"

What I want is to dispatch to the first rule if the node has an nsubj and a dobj edge coming out of it. I don't care about what else it might have.

Clearly my example function doesn't do this, since it requires the edges to be present in the right order, and it won't match if more edges are present.

One approach could be to use guards for more expressivity, I can do:

m (w, es) | (isJust.lookup "nsubj") es && (isJust.lookup "dobj") es = ...
          | ...
          | otherwise = error ...

But that's a lot more paintful, and I don't even get a handle on the target nodes.

Is there a standard way to write pattern matching parsers over graphs like mine? Or is there perhaps some magic based on the Maybe monad..?

Était-ce utile?

La solution

You can use pattern guards:

{-# LANGUAGE PatternGuards #-}

m (w, es) | Just nsubj <- lookup "nsubj" es, Just dobj <- lookup "dobj" es = ...
          | ...
          | otherwise = error ...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top