Open nobeh opened 9 years ago
It looks like you are trying to do an instanceof match. There is a built in typeOf matcher in Motif that should work for this scenario. I built out some code quick to test it out, and it does work, but you'll need to cast the result. Make sure you called one of the getMatch
or doMatch
methods to actually perform the matching also.
public static <A, B> Map_<A, B> put_motif(final Map_<A, B> ms, final A k, final B v) {
InsertAssoc_<A, B> result = (InsertAssoc_) match(ms)
.when(typeOf(EmptyMap_.class))
.get(x -> new InsertAssoc_<>(Tuple2.of(k, v), new EmptyMap_<>()))
.when(typeOf(InsertAssoc_.class))
.get(x -> k.equals(x.pair.first())
? new InsertAssoc_<>(Tuple2.of(k, v), x.map)
: new InsertAssoc_<>(Tuple2.of(k, v), put_motif(x.map, k, v)))
.getMatch();
return result;
}
Thank you for your reply. It indeed works.
Let me continue with a more specific question. Let's focus on the part typeOf(InsertAssoc_.class)
. In a pure functional language with support of pattern matching, I would write the same check as the following as if can be done with Motif:
.when(eq(InsertAssoc_(Tuple2.of(kk, vv), innerMap)))
.get( x -> kk.equals(k)
? new InsertAssoc_<>(Tuple2.of(kk, v), innertMap)
: new InsertAssoc_<>(Tuple2.of(kk, vv), put_motif(innerMap, k, v))
I tried to make Map_
an implementation of Case2<Tuple2<A, B>, Map_>
and then tried:
match(ms).when(typeOf(EmptyMap_.class))
.get(x -> new InsertAssoc_<>(Tuple2.of(k, v), new EmptyMap_()))
.when(case2(InsertAssoc_.class, typeOf(Tuple2.class), typeOf(Map_.class)))
.get((Tuple2 p, Map_ m) -> p.first().equals(k)
? new InsertAssoc_<>(Pair(k, v), m)
: new InsertAssoc_<>(Pair(p.first(), p.second()), put_motif(m, k, v)))
;
No luck as I get other compile errors.
To me this looks a deep extraction with parameters. But I do not know how to do it in Motif. Is this possible? Thanks.
Your Case2 code is really close. You can use the Tuple2 match pattern to extract the values directly.
Try this:
match(ms).when(typeOf(EmptyMap_.class))
.get(x -> new InsertAssoc_<>(Tuple2.of(k, v), new EmptyMap_()))
.when(case2(InsertAssoc_.class, tuple2(any(), any()), typeOf(Map_.class)))
.get(
(key, value, m) -> key.equals(k)
? new InsertAssoc_<>(Tuple2.of(k, v), m)
: new InsertAssoc_<>(Tuple2.of(key, value), put_motif(m, k, v)))
;
Let's consider the following naive example:
and now I'd like to define a method
put
with the following logic:Trying to do it with Motif as the following leads to compile errors:
and the compilation error is basically type mismatch. In this example, I am trying to use Hamcrest matchers. Is there another way? What's the correct way to do this in Motif?