module Text.Regex.TDFA.IntArrTrieSet where
import Data.Array.IArray(Array,(!),listArray)
data TrieSet v = TrieSet { value :: v
, next :: Array Int (TrieSet v) }
lookupAsc :: TrieSet v -> [Int] -> v
lookupAsc (TrieSet {value=v,next=n}) =
(\keys -> case keys of [] -> v
(key:keys') -> lookupAsc (n!key) keys')
fromBounds :: (Int,Int)
-> ([Int] -> v)
-> TrieSet v
fromBounds (start,stop) keysToValue = build id start where
build keys low = TrieSet { value = keysToValue (keys [])
, next = listArray (low,stop)
[build (keys.(x:)) (succ x) | x <- [low..stop] ] }
fromSinglesMerge :: v
-> (v->v->v)
-> (Int,Int)
-> (Int->v)
-> TrieSet v
fromSinglesMerge emptyValue mergeValues bound keyToValue = trieSet where
trieSet = fromBounds bound keysToValue'
keysToValue' keys =
case keys of
[] -> emptyValue
[key] -> keyToValue key
_ -> mergeValues (keysToValue (init keys)) (keysToValue [last keys])
keysToValue = lookupAsc trieSet
fromSinglesSum :: ([v]->v)
-> (Int,Int)
-> (Int->v)
-> TrieSet v
fromSinglesSum mergeValues bound keyToValue = trieSet where
trieSet = fromBounds bound keysToValue'
keysToValue' = mergeValues . map keyToValue