Mapping-0.1.0.1: Mapping.hs
-- Copyright (C) 2018 Zaoqi
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published
-- by the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module Mapping(
Mapping(),
mappingRef,
mappingSet,
mappingUnion,
mappingMayRemove,
mappingHas,
mappingToList,
listToMapping,
) where
type List a = [a]
data Mapping k v = MappingNil | MappingNode (Mapping k v) k v (Mapping k v) deriving Show
mappingRef :: Ord k => Mapping k v -> k -> v -> v
mappingRef (MappingNode l mk v r) k d =
case compare k mk of
LT -> mappingRef l k d
EQ -> v
GT -> mappingRef r k d
mappingRef MappingNil _ d = d
mappingSet :: Ord k => Mapping k v -> k -> v -> Mapping k v
mappingSet (MappingNode l mk mv r) k v =
case compare k mk of
LT -> MappingNode (mappingSet l k v) mk mv r
EQ -> MappingNode l mk v r
GT -> MappingNode l mk mv (mappingSet r k v)
mappingSet MappingNil k v = MappingNode MappingNil k v MappingNil
mappingUnion :: Ord k => (k -> v -> v -> v) -> Mapping k v -> Mapping k v -> Mapping k v
mappingUnion combine (MappingNode l1 k1 v1 r1) (MappingNode l2 k2 v2 r2) =
let
l = mappingUnion combine l1 l2
r = mappingUnion combine r1 r2
in
case compare k1 k2 of
LT -> mappingUnion combine r l
EQ -> MappingNode l k1 (combine k1 v1 v2) r
GT -> mappingUnion combine l r
mappingUnion _ MappingNil x = x
mappingUnion _ x MappingNil = x
mappingMayRemove :: Ord k => Mapping k v -> k -> Mapping k v
mappingMayRemove (MappingNode l mk v r) k =
case compare k mk of
LT -> MappingNode (mappingMayRemove l k) mk v r
EQ -> MappingNil
GT -> MappingNode l mk v (mappingMayRemove r k)
mappingMayRemove MappingNil _ = MappingNil
mappingHas :: Ord k => Mapping k v -> k -> Bool
mappingHas (MappingNode l mk v r) k =
case compare k mk of
LT -> mappingHas l k
EQ -> True
GT -> mappingHas r k
mappingHas MappingNil _ = False
mappingToList :: Mapping k v -> List (k, v)
mappingToList (MappingNode l k v r) = (mappingToList l) ++ ((k, v) : mappingToList r)
mappingToList MappingNil = []
listToMapping :: Ord k => List (k, v) -> Mapping k v
listToMapping ((k, v) : xs) = mappingSet (listToMapping xs) k v
listToMapping [] = MappingNil
instance (Eq k, Eq v) => Eq (Mapping k v) where
x == y = mappingToList x == mappingToList y
instance (Ord k, Ord v) => Ord (Mapping k v) where
compare x y = compare (mappingToList x) (mappingToList y)