Cannot merge conditionals
Closed this issue · 4 comments
I'm trying to write a schema that merges two conditionals like so:
(def foo
(merge
(s/if #(:foo %)
{:foo s/Str}
{:foo (s/eq nil)})
(s/if #(:bar %)
{:bar s/Str}
{:bar (s/eq nil)})))
However, it seems that once I load this it only keeps the second (s/if ...
and does away with the first
circle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) (s/if #(:bar %) {:bar s/Str} {:bar (s/eq nil)})))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13324 {:bar Str} clojure.core$constantly/fn--4614 {:bar (eq nil)})
circle-migrator.core=>
I tried to reduce the complexity a bit by removing the second (s/if ...
circle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) {:bar s/Str}))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13327 {:foo Str} clojure.core$constantly/fn--4614 {:foo (eq nil)})
circle-migrator.core=> (s/validate foo {:foo "foo" :bar "bar"})
ExceptionInfo Value does not match schema: {:bar disallowed-key} schema.core/validator/fn--622 (core.clj:155)
circle-migrator.core=>
So it seems like conditionals cannot be merged once the conditional has resolved. This seems like unintuitive behavior (at least to me). Is this a bug or is it on purpose?
If returns a conditional schema, which is a record that implements the
schema protocol and contains a list of conditions and subschemas inside.
Merge merges the keys of the record, which is not what you want.
If you look at the implementation of conditional schema you should be able
to see how to properly merge what's inside. I'm on my phone but can
provide details later if you can't figure it out.
On Wed, Sep 21, 2016, 4:10 AM Justin Cowperthwaite notifications@github.com
wrote:
I'm trying to write a schema that merges two conditionals like so:
(def foo
(merge
(s/if #(:foo %)
{:foo s/Str}
{:foo (s/eq nil)})
(s/if #(:bar %)
{:bar s/Str}
{:bar (s/eq nil)})))However, it seems that once I load this it only keeps the second (s/if ...
and does away with the firstcircle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) (s/if #(:bar %) {:bar s/Str} {:bar (s/eq nil)})))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13324 {:bar Str} clojure.core$constantly/fn--4614 {:bar (eq nil)})
circle-migrator.core=>I tried to reduce the complexity a bit by removing the second (s/if ...
circle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) {:bar s/Str}))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13327 {:foo Str} clojure.core$constantly/fn--4614 {:foo (eq nil)})
circle-migrator.core=> (s/validate foo {:foo "foo" :bar "bar"})ExceptionInfo Value does not match schema: {:bar disallowed-key} schema.core/validator/fn--622 (core.clj:155)
circle-migrator.core=>So it seems like conditionals cannot be merged once the conditional has
resolved. This seems like unintuitive behavior (at least to me). Is this a
bug or is it on purpose?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#375, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIPplT8GamSHoMtyIAJfK09ZjNN7ZnBks5qsIPogaJpZM4KCTSr
.
To elaborate, this is the definition of the conditional record:
https://github.com/plumatic/schema/blob/master/src/cljx/schema/core.cljx#L477
and preds-and-schemas is a sequence of [predicate, schema] pairs, so you
can delve into there to merge your map with the containing schemas.
On Wed, Sep 21, 2016 at 8:49 AM, Jason Wolfe jason@w01fe.com wrote:
If returns a conditional schema, which is a record that implements the
schema protocol and contains a list of conditions and subschemas inside.
Merge merges the keys of the record, which is not what you want.If you look at the implementation of conditional schema you should be able
to see how to properly merge what's inside. I'm on my phone but can
provide details later if you can't figure it out.On Wed, Sep 21, 2016, 4:10 AM Justin Cowperthwaite <
notifications@github.com> wrote:I'm trying to write a schema that merges two conditionals like so:
(def foo
(merge
(s/if #(:foo %)
{:foo s/Str}
{:foo (s/eq nil)})
(s/if #(:bar %)
{:bar s/Str}
{:bar (s/eq nil)})))However, it seems that once I load this it only keeps the second (s/if
... and does away with the firstcircle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) (s/if #(:bar %) {:bar s/Str} {:bar (s/eq nil)})))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13324 {:bar Str} clojure.core$constantly/fn--4614 {:bar (eq nil)})
circle-migrator.core=>I tried to reduce the complexity a bit by removing the second (s/if ...
circle-migrator.core=> (def foo (merge (s/if #(:foo %) {:foo s/Str} {:foo (s/eq nil)}) {:bar s/Str}))
#'circle-migrator.core/foo
circle-migrator.core=> foo
(conditional circle-migrator.core/fn--13327 {:foo Str} clojure.core$constantly/fn--4614 {:foo (eq nil)})
circle-migrator.core=> (s/validate foo {:foo "foo" :bar "bar"})ExceptionInfo Value does not match schema: {:bar disallowed-key} schema.core/validator/fn--622 (core.clj:155)
circle-migrator.core=>So it seems like conditionals cannot be merged once the conditional has
resolved. This seems like unintuitive behavior (at least to me). Is this a
bug or is it on purpose?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#375, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIPplT8GamSHoMtyIAJfK09ZjNN7ZnBks5qsIPogaJpZM4KCTSr
.
I ended up solving it with...
(def foo
(s/conditional
#(and (:foo %) (bar %))
(merge {:foo s/Str} {:bar s/Str})
...
for each of the 4 possible combinations, which I think is what you were suggesting.
Great, that will work too. Thanks for following up!