【问题标题】:Adding Syntactic Sugar to Make Prismatic Schema Look Like Core.Typed/Haskell添加语法糖以使 Prismatic Sc​​hema 看起来像 Core.Typed/Haskell
【发布时间】:2016-09-17 01:13:10
【问题描述】:
  1. 考虑core.typed 注释函数的方式:

    (t/ann typed-function [t/Str :-> t/Str])
    
  2. 现在考虑 Prismatic Sc​​hema 注释函数的方式:

    (s/defn schema-function :- s/Str
           [arg :- s/Str]
           arg)
    

就个人而言,我发现core.typed 注释函数的方式在精神上更清晰,更接近于 Haskell 等强类型语言。

问题: 有没有办法用 Prismatic Sc​​hema 在 clojure 中制作某种宏或函数,具有 (2) 的效果,但具有 (1) 的视觉外观?也就是说,类似于以下内容:'

(custom-annotation-macro schema-function [s/Str :-> s/Str])
(defn schema-function [arg] arg)

这样的效果只是

(s/defn schema-function :- s/Str
      [arg :- s/Str]
       arg)

【问题讨论】:

    标签: haskell clojure clojurescript plumatic-schema clojure-core.typed


    【解决方案1】:

    为了说明如何使用两个宏来解决这个问题:

    (def type-annots (atom (hash-map)))
    
    (defn add-type-annot [fn-name ty]
      (swap! type-annots #(conj % [fn-name ty])))
    
    (defmacro custom-annotation-macro [fn-name ty]
      (add-type-annot fn-name ty)
      nil)
    
    (defn split-fun-type [ty]
      ;; You will need to write this one; 
      ;; it should split [a :-> b :-> c] to [[a b] c]
      ['[s/Str s/Int] 's/Str])
    
    (defmacro defn-typed [fn-name args & body]
      (let [ty (get @type-annots fn-name)]
        (if ty
          (let [[arg-types ret-ty] (split-fun-type ty)
                args-typed (apply vector (apply concat (map vector args arg-types)))]
            `(s/defn ~fn-name :- ~ret-ty ~args-typed ~@body))
          `(defn ~fn-name ~args ~@body))))
    

    我没有费心去实现split-fun-type,因为我并不真正了解Clojure;以上是基于我对 Lisp 的理解。

    【讨论】:

      猜你喜欢
      • 2014-08-14
      • 2015-04-16
      • 2015-05-24
      • 2016-07-16
      • 2020-07-24
      • 2016-09-28
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多