(defn structure->typed [coeff-functions basis]
(let [vector-basis (b/basis->vector-basis basis)
oneform-basis (b/basis->oneform-basis basis)
arg-types (loop [cf coeff-functions
acc []]
(if-not (s/structure? cf)
acc
(let [shape (s/opposite-orientation
(s/orientation cf))
t (case shape
::s/up ::vf/vector-field
::s/down ::ff/oneform-field)]
(recur (nth cf 0)
(conj acc t)))))]
(-> (fn indexed-fn [& args]
(assert (= (count args)
(count arg-types))
(str "The number of args " (count args)
" did not match the expected arity " (count arg-types) ". "
"Please supply args corresponding to the expected types " arg-types "."))
(assert (every? true? (map (fn [arg arg-type]
(isa? (v/kind arg) arg-type))
args arg-types))
(str "Invalid arguments: " args ". "
"Please supply args corresponding to the expected types " arg-types "."))
(letfn [(lp [args arg-types]
(if (empty? args)
m/one-manifold-function
(let [arg (first args)
arg-type (first arg-types)]
(cond (isa? arg-type ::vf/vector-field)
(s/mapr (fn [etilde]
(* (etilde arg)
(lp (rest args)
(rest arg-types))))
oneform-basis)
(isa? arg-type ::ff/oneform-field)
(s/mapr (fn [e]
(* (arg e)
(lp (rest args)
(rest arg-types))))
vector-basis)))))]
(* (lp args arg-types)
coeff-functions)))
(with-argument-types arg-types))))