Fork me on GitHub
#core-typed
<
2022-07-11
>
Prashant19:07:10

Hi, I was trying below type annotation but kept on getting error on (t/check-ns-clj) I am using Typed Clojure (ver. 1.0.31) and was implementing delayed evaluation for function arguments. Code:

(require '[typed.clojure :as t])

(t/defalias Lazy
            (t/TFn [[x :variance :covariant]]
                   (t/IFn [:-> x])))
;; => nil

(t/ann lazy-int [t/Int :-> (Lazy t/Int)])
;; => nil

(defn lazy-int
  [elem]
  (fn [] elem))
;; => #'some-ns/lazy-int

(t/defalias LazyList
            (t/TFn [[y :variance :covariant]]
                   (t/U nil
                        (Lazy (t/HMap :mandatory
                                      {:head (Lazy y)
                                       :tail (LazyList y)})))))
;; => nil

(t/ann to-lazy-list [(t/SequentialColl t/Int) :-> (LazyList t/Int)])
;; => nil

(defn to-lazy-list
  [xs]
  #(when (seq xs)
    {:head (lazy-int (first xs))
     :tail (to-lazy-list (rest xs))}))

;; => #'some-ns/to-lazy-list
Error details:
Type mismatch:

Expected: 	(t/HMap :mandatory {:head (some-ns/Lazy t/Int), :tail (some-ns/LazyList t/Int)})

Actual: 	nil

in:
nil

Execution error (ExceptionInfo) at clojure.core.typed.errors/print-errors! (errors.cljc:290).
Type Checker: Found 1 error
1. I couldn't make much sense of the error or the debug info. I am using t/U with nil in the definition of LazyList , however debug info says otherwise EDIT: Issue got fixed after further debugging. Following is the correct Type def (`Lazy` was not wrapping t/Ufacepalm)
(t/defalias LazyList
            (t/TFn [[y :variance :covariant]]
                   (Lazy
                     (t/U nil
                          (t/HMap :mandatory
                                  {:head (Lazy y)
                                   :tail (LazyList y)})))))
1. Is there a better way to define LazyList (i.e. the :tail part contained in t/HMap). Can t/Rec be used in this case (I couldn't figure it out)? Nudge in the right direction would be greatly appreciated 🙂

ambrosebs01:07:11

This looks right. You don't need a t/Rec because a t/defalias is in scope in its body. Wrapping (t/Rec (t/TFn would probably confuse subtyping also.

👍 1