Fork me on GitHub

how do I express this in a schema?

{"hi" {:greeting "hi" :id 1} "hello" {:greeting "hello" :id 2} "hiee" {:greeting "hiee" :id 3}}
I have a function that transforms a map like this
[{:greeting "hi" :id 1}{:greeting "hello" :id 2}{:greeting "hiee" :id 3}]
into the one above, the values of :greeting aren’t known before hand


maybe: [:map-of :string [:map [:id :int] [:greeting :string]]]


That is a good suggestion, but I want to say that the key of the map has to the be equal to the value of the :greeting key. so [:map-of :string [:map [:id :int] [:greeting :string]]] would be valid for {"foostring" {:greeting "hi" :id 3}} but the above won’t be valid


I don’t know if what I’m tryign to do is an anti-pattern:sweat_smile:


no, it’s all valid, maybe:

(def Schema
    [:map-of :string [:map [:id :int] [:greeting :string]]]
    [:fn (partial every? (fn [[k d]] (= k (:greeting d))))]]))

 {"hi" {:greeting "hi" :id 1}
  "hello" {:greeting "hello" :id 2}
  "hiee" {:greeting "hiee" :id 3}})
; => true

 {"hi" {:greeting "<<invalid>>" :id 1}
  "hello" {:greeting "hello" :id 2}
  "hiee" {:greeting "hiee" :id 3}})
; => false

clojure-spin 1

m/explain here doesn’t produce correct place of error, could should do it, we could tune either :fn to support returning custom explain-results, or add support for generic :explain key for keys, or something. Someone should write an issue out of this.


@U055NJ5CC thank you for your help. that was exactly what I was looking for.


I believe I'm just being daft here but I haven't been able to figure this out for more than an hour so: How do I resolve a keyword to a schema in the registry?

(def registry
  (atom {}))

(defn register! [type ?schema]
  (swap! registry assoc type ?schema))

;; Combine the default registry with our own mutable registry.
    (mreg/fast-registry (malli/default-schemas))
    (mreg/mutable-registry registry)))

(register! :db/kasse
    [:id                            [:int {:primary-key true :db-generated true}]]
    [:odlingsplats                  [:string {:foreign-key "odlingsplatser"}]]
    [:diameter_m                    :int]
    [:djup_m                        :int]
    [:volym_m2                      [:int {:db-generated true}]]])

 (malli/schema-walker identity))
;; => :db/kasse
I've tried wrapping :db/kasse in different functions from malli but none seem to do the lookup. The lookup function in the core namespace is private. Just running (:db/kasse malli/default-registry) does not work either. (malli/schema :db/kasse) seems like the obvious choice but it seemingly has no effect.
 (malli/schema :db/kasse)
 (malli/schema-walker identity))
;; => :db/kasse


the :db/kasse returned is a Malli Schema instance, it’s print output is just the form, so looks like keyword. It’s type is :malli.core/schema, which is the internal eager reference, like a Var in Clojure. If you want to get the schema behind it, you can m/deref it. But, calling m/validate on :db/kasse works too. the :malli.core/schema forwards the calls to the actual instance, like Var. Hope this helps.


also, walking it just work, try something like (m/ast :db/kasse) to verify

👀 1

Thank you, dereffing worked perfectly. Though I'm not sure I understand the latter reply:

(let [schema (malli/schema :db/kasse)]                                                                                
  (prn (type schema))                                                                                                 
   (malli/schema-walker identity))) 
;; => :db/kasse
;; printed: :malli.core/schema


hi all! Just started using malli and I have what I think is a pretty newbie question: Is there a way, in the context of a :map schema declaration to have mutually exclusive keys? That is “map should contain :a and :b together or :c by itself”.

Ben Sless17:01:53

Not atm, but it's an often requested feature

👍 1

Hi, I’ve been playing with the idea of using Malli as a way to define the main data model of an application. Many features are already in Malli I believe. One thing that might be missing is an easy way to generate consistent test and seed data. Maybe something like composite types are an useful addition?

(register! :user/first-name [:enum "john" "joe" "alex"])
(register! :user/last-name [:enum "smith" "wood" "lee"])

(register! :user/full-name
           [:composite {:schema string?
                        :compose (fn [first-name last-name]
                                   (str first-name " " last-name))
                        :fields [:user/first-name :user/last-name]}])

(register-entity! ::user

(generate ::user)
;; => #:user{:first-name "joe", :last-name "wood", :full-name "joe wood"}
More here

👀 1
Ben Sless19:01:47

Did you just implement unification?


Not consciously 😅 Maybe accidentally? I was just thinking how do I get meaningful seed and test data when I’m just defining my attributes and entities


@UK0810AQ2 I see you did some work on unification yourself ( and My approach is not that advanced (or complete)

Ben Sless20:01:49

It's okay, my approach sucked anyway I'm becoming convinced the only solution is embedding micro kanren and I'm scared


Haha I can imagine