Searching a tree while storing the path
type Pattern = [PatternPart]
data Patt开发者_开发技巧ernPart =
MatchTuple [PatternPart] |
Named String |
MatchAny
data ArguementIndex =
InTuple Int ArguementIndex | -- arguement is in tuple at index Int, then at index...
ArgIndex Int
testPattern = [Any, MatchTuple[Any, Named "hello"]]
getArgIndex :: Pattern -> String -> Maybe ArguementIndex
I need to write a function getArgIndex
to search testPattern
for "hello"
and return InTuple 1 (ArgIndex 1)
getArgIndex [Any, Any, MatchTuple [Named "hi"]] "hi" = Just (InTuple 2 (ArgIndex 0))
Another example
I cant come up with an elegant way to do this.
Please advise.
How do you know there's only one match?
Try something like this:
import Data.Maybe (listToMaybe)
getArgIndex :: Pattern -> String -> Maybe ArguementIndex
getArgIndex haystack needle = listToMaybe (getArgIndices haystack needle)
getArgIndices :: Pattern -> String -> [ArguementIndex]
getArgIndices haystack needle
= concat $ zipWith f [0..] haystack
where f i (MatchTuple haystack') = map (InTuple i) $ getArgIndices haystack' needle
f i (Named item) | item == needle = [ArgIndex i]
f i _ = []
(Untested.) This assumes you want the first match if there is more than one.
(You will want to use the proper spelling of "argument".)
Personally, I would put the arguments in the opposite order, if I could:
getArgIndices' :: String -> Pattern -> [ArguementIndex]
getArgIndices' needle = g
where g = concat . zipWith f [0..]
f i (MatchTuple haystack) = map (InTuple i) $ g haystack
f i (Named item) | item == needle = [ArgIndex i]
f i _ = []
精彩评论