Вопрос

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..?

Это было полезно?

Решение

You can use pattern guards:

{-# LANGUAGE PatternGuards #-}

m (w, es) | Just nsubj <- lookup "nsubj" es, Just dobj <- lookup "dobj" es = ...
          | ...
          | otherwise = error ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top