开发者

Searching a tree while storing the path

开发者 https://www.devze.com 2023-04-12 04:04 出处:网络
type Pattern = [PatternPart] data Patt开发者_开发技巧ernPart = MatchTuple [PatternPart] | Named String |
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 _                             = []
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号