haw*_*eye 9 haskell clojure typeclass multimethod clojure-protocol
这是关于Clojure与其他语言(如Haskell)的表现力的问题.更广泛的问题是表达问题的解决方案
这个问题得出的结论是,一般来说Clojure协议(和多方法)的表达力要低于Haskell类型类,因为协议在第一个参数上调度,而Haskell类型类可以在返回类型上调度.(现在我认为这种推理非常有趣,并且没有兴趣开始语言大战.我只是对思想的清晰度感兴趣).
作为打破这种推理的一部分 - 我的问题是 - 我们不能制作一个Clojure多方法来调度返回类型(或类型提示).我想我们可以将以下表达式放入Clojure多方法中:
(= java.lang.String (:tag (meta #'my-string)))
Run Code Online (Sandbox Code Playgroud)
功能是:
(defn ^String my-string []
"hello world")
Run Code Online (Sandbox Code Playgroud)
编辑:关键是我可以运行:
(meta #'my-string)
Run Code Online (Sandbox Code Playgroud)
并在没有功能评估的情况下获得以下结果:
{:arglists ([]), :ns #<Namespace push-price.core>, :name my-string, :column 1,
:line 1, :file "/private/var/folders/0l/x6hr0t1j2hvcmm_sqq04vdym0000gn/T/form-
init7576840885484540032.clj", :tag java.lang.String}
Run Code Online (Sandbox Code Playgroud)
即我没有评估我的功能的预期类型的一些信息.
编辑3(2014年4月24日):
假设我有以下类型:(deftype string-type [])
(deftype int-type [])
Run Code Online (Sandbox Code Playgroud)
然后我根据这些类型定义了以下函数:
(defn #^{:return-type string-type} return-string []
"I am returning a string")
(defn #^{:return-type int-type} return-int []
42)
Run Code Online (Sandbox Code Playgroud)
现在我编写一个函数来调度它们的返回类型,如下所示:
(defn return-type-dispatch [fn-arg]
(let [return-type (:return-type (meta fn-arg))]
(cond
(= return-type string-type)
"This function has a return type of the string type"
(= return-type int-type)
"This function has a return type of the integer type"
:else (str "This function has a return type of:" return-type))))
Run Code Online (Sandbox Code Playgroud)
然后我编写一个宏来在编译时运行它
(defmacro compile-time-type-check-string []
(println (return-type-dispatch #'return-string)))
(compile-time-type-check-string)
Run Code Online (Sandbox Code Playgroud)
然后我测试它是这样的:
lein uberjar
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
$ lein uberjar
Compiling dispatch-type-compile-time.core
This function has a return type of:class dispatch_type_compile_time.core.string-type
...
Run Code Online (Sandbox Code Playgroud)
所以我似乎是在返回类型上调度.
让我们假设在Clojure中有返回类型多态性.这将允许我们编写类似Haskell类的东西
class Default a where def :: a
Run Code Online (Sandbox Code Playgroud)
在Haskell中这是有效的,因为有一个片段就像编译时错误一样
def
Run Code Online (Sandbox Code Playgroud)
因为众所周知,在编译时这意味着什么是模棱两可的.同样,如果我们要编写Clojure片段
(def)
Run Code Online (Sandbox Code Playgroud)
它不可能知道如何将该调用分派给适当的实例.更清楚的是,Clojure的评估顺序是片段中的评估顺序
(foo x y z)
Run Code Online (Sandbox Code Playgroud)
表达式x,y并z在之前得到评估foo.为了(def)工作,它需要以某种方式检查foo(并因此强制其评估)以获得关于将如何使用返回值的信息(def).
这可以在CPS转换之后完成,在这种情况下(def),转换为类似的函数(在Haskell类型表示法中)
class Default a where def :: (a -> r) -> r
Run Code Online (Sandbox Code Playgroud)
现在我们看到我们可以检查continuation函数,以便了解它所期望的参数类型的信息,然后发送它.
最后,给定足够的宏魔法可以做到这一点......但现在可能比在Clojure上实现Haskell风格类型系统更省力.类型化的Clojure可能是一个很好的模型,除了它已被明确设计,以便Clojure的语义不受推断类型的影响.这正是返回类型多态中发生的事情,因此在Typed Clojure中显然是不可能的.
| 归档时间: |
|
| 查看次数: |
564 次 |
| 最近记录: |