Consider the following apply-like function:
(defn apply [f v]
(f v))
I would like to specify this function in such a way that its return value satisfies the same specification as the return value of f. Furthermore I would also like to specify that the input value v satisfies the specification of the input of f.
My attempt at specifying something like this is the following:
(s/fdef apply
:args (s/cat :f (s/fspec :args (s/cat :v any?) :ret any?))
:ret any?)
This specification is very loose. What I would like to do is to quantify over two predicates returned? and argument? to further constrain the specification.
(s/fdef apply
:args (s/cat :f (s/fspec :args (s/cat :v argument?) :ret returned?))
:ret returned?)
Where argument? and returned? represent two arbitrary predicates. From what I understand this type of quantification is not possible in clojure.spec.
More generally, this type of behavior can be naturally expressed using any parametric type system, including Java's generics. Is this also specifiable using clojure.spec?
You would need some function to figure out the spec for the input argument
f. I am not aware of any such function so here is one possibility. Yes, I know, it is pretty dirty:Then you can use that function to write your the spec of some other function that I call
my-apply(there is already a functionapplyin core):But I wouldn't recommend you doing this...