Reputation: 161
MapKey k => (k -> a -> Optional c) -> (k -> b -> Optional c) -> (k -> a -> b -> Optional c) -> Map k a -> Map k b -> Map k c
difficult to understand syntax please provide example for declaring this merge for map values and also provide brief description how to construct it with simple examples
Upvotes: 0
Views: 164
Reputation: 116139
If you have two maps with the same key type
m1 : Map k a
m2 : Map k b
You can merge them into a single map Map k c
calling merge
like this:
merge f1 f2 f12 m1 m2
where
f1 : k -> a -> Optional c
specifies what to do if a key was found in m1
but not in m2
. Here f1
is passed both the key and its corresponding value in m1
.f2 : k -> b -> Optional c
specifies what to do if a key was found in m2
but not in m1
. Here f2
is passed both the key and its corresponding value in m2
.f12 : k -> a -> b -> Optional c
specifies what to do if a key was found in both m1
and m2
. Here f12
is passed the key, its corresponding value in m1
, and its corresponding value in m2
.In each case, return None
is you want the key to be missing in the result map. Return Some x
if you want the the key to be present and associated to value x
.
Upvotes: 2
Reputation: 995
Make sure you have a read of the docs for the function.
merge
takes three functions and two maps. The two maps have the same key type, but different value types. The map resulting form merge
has to have a single value type, of course, so we have to tell merge what to do if
Let's for example say we have a map Map Int Text
and a map Map Int Bool
which we want to merge, and let's just say the resulting map should indicate in which of the three cases above we are. We can define a type for that:
data EitherOrBoth a b
= EOBLeft a
| EOBRight b
| EOBBoth (a, b)
deriving (Eq, Show)
Now we can define functions to say "Stick a value in Left", "Stick a value in Right", and "Stick two values in a tuple" in merge:
mergeWithBoth : (MapKey k) => Map k a -> Map k b -> Map k (EitherOrBoth a b)
mergeWithBoth = merge (\k x -> Some (EOBLeft x)) (\k y -> Some (EOBRight y)) (\k x y -> Some (EOBBoth (x, y)))
Try the whole thing out using a script:
import Daml.Script
import DA.Next.Map (Map, MapKey, merge, fromList)
data EitherOrBoth a b
= EOBLeft a
| EOBRight b
| EOBBoth (a, b)
deriving (Eq, Show)
mergeWithBoth : (MapKey k) => Map k a -> Map k b -> Map k (EitherOrBoth a b)
mergeWithBoth = merge (\k x -> Some (EOBLeft x)) (\k y -> Some (EOBRight y)) (\k x y -> Some (EOBBoth (x, y)))
testMerge = script do
let
mapIntText : Map Int Text = fromList[(1, "Hello"), (2, "World")]
mapIntDec : Map Int Bool = fromList[(2, True), (3, False)]
assert (mergeWithBoth mapIntText mapIntDec
== fromList [(1, EOBLeft "Hello"),(2, EOBBoth ("World", True)), EOBRight False)])
return (mergeWithBoth mapIntText mapIntDec)
Upvotes: 2