malli

2024-09-29T13:01:21.740239Z

Hello everyone! Is it possible in Malli to create function schema with second argument dependent from the first one? Something like this:

(m/=> price->str [:function
                  [:=> [:cat [:enum :bytes :minutes] :int] :string]
                  [:=> [:cat [:= :date] [:map
                                         {:closed true}
                                         [:days   {:optional true} :int]
                                         [:months {:optional true} :int]
                                         [:years  {:optional true} :int]]] :string]])
But this approach returns :malli.core/duplicate-arities error...

adham 2024-09-29T13:03:00.279839Z

So is it a function with two positional arguments that can be either 1. an enum of :bytes, :minutes or 2. a date and a map?

2024-09-29T13:04:40.472839Z

Three different variavnts: • :bytes keyword and integer value; • :minutes keyword and integer value; • :date keyword and a map.

2024-09-29T13:10:57.509139Z

It would be nice to use multimethod, but like I know so far Malli doesn't support instrumentation for multimethods... doesn't it?

adham 2024-09-29T13:35:12.711289Z

Yeah I don't remember it supporting multi-methods, perhaps try something with an :or and maps for the argument?

[:or 
  [:map [:key1 :int]]
  [:map [:key2 :int]]]
    

adham 2024-09-29T13:36:13.233819Z

{:dispatch :bytes, :value 123}
{:dispatch :minutes, :value 123}
{:dispatch :date, :value {}}

2024-09-29T13:38:59.898709Z

:or not working. It throws invalid-schema. Thank you for approach with map. It will definitely work, but isn't suitable for my case. I will validate input inside the function then despite it is not so convient.

Kirill Chernyshov 2024-09-29T14:24:08.231669Z

you can use function guards to validate arguments instead of inside of the function https://github.com/metosin/malli/blob/master/docs/function-schemas.md#function-guards

👍 1
2024-09-29T14:27:03.498049Z

Yes. Not a bad idea!