首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在返回类型时发送吗?(和Haskell Typeclasses一样有表现力)

在返回类型时发送吗?(和Haskell Typeclasses一样有表现力)
EN

Stack Overflow用户
提问于 2014-03-30 04:17:04
回答 1查看 732关注 0票数 9

这是一个关于Clojure与其他语言(如Haskell )的表现力的问题。更广泛的问题是表达问题的解决方案。

这个问题得出的结论是,在一般情况下,Clojure协议(和多方法)的表达不如Haskell类型,因为协议是在第一个参数上分派的,而Haskell类型协议可以在返回类型上进行调度。(现在我认为这个推理很有趣,对发动语言战争没有兴趣。我只是对思路的清晰感兴趣)。

作为分解这个推理的一部分--我的问题是--不能创建一个对返回类型(或类型提示)进行调度的Clojure。我认为我们可以将以下表达式放入Clojure multimethod中:

代码语言:javascript
复制
(= java.lang.String (:tag (meta #'my-string)))

其职能是:

代码语言:javascript
复制
(defn ^String my-string [] 
  "hello world")

编辑:关键是我可以运行:

代码语言:javascript
复制
(meta #'my-string)

并在不进行功能评估的情况下得到以下结果:

代码语言:javascript
复制
{: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}

我有一些关于我的功能的预期类型的信息,但没有对它进行评估。

编辑3(2014年4月24日):

假设我有以下类型:(deftype string-type [])

代码语言:javascript
复制
(deftype int-type [])

然后,我根据这些类型定义了以下函数:

代码语言:javascript
复制
(defn #^{:return-type string-type} return-string [] 
  "I am returning a string")

(defn #^{:return-type int-type} return-int [] 
  42)

现在,我编写了一个函数,用于对它们的返回类型进行分派,如下所示:

代码语言:javascript
复制
(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))))

然后编写一个宏来在编译时运行它。

代码语言:javascript
复制
(defmacro compile-time-type-check-string []
  (println (return-type-dispatch #'return-string)))

(compile-time-type-check-string)

然后我像这样测试它:

代码语言:javascript
复制
lein uberjar

这将产生以下结果:

代码语言:javascript
复制
$ lein uberjar
Compiling dispatch-type-compile-time.core
This function has a return type of:class dispatch_type_compile_time.core.string-type
...

因此,我似乎是在发送返回类型。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-30 04:31:14

让我们想象一下Clojure中存在返回类型多态性。这样我们就可以编写类似Haskell类的东西。

代码语言:javascript
复制
class Default a where def :: a

在Haskell中,这是因为有这样一个片段是编译时错误的

代码语言:javascript
复制
def

众所周知,编译时对于这意味着什么是模棱两可的。以类似的方式,如果我们要编写Clojure片段

代码语言:javascript
复制
(def)

不可能知道如何将该调用分派到适当的实例。更清楚的是,Clojure的计算顺序是片段中的计算顺序

代码语言:javascript
复制
(foo x y z)

表达式xyz都是在foo之前计算的。为了使(def)工作,它需要以某种方式检查foo (从而强制它的计算),以便获得关于如何使用(def)的返回值的信息。

这可以在CPS转换之后完成,在这种情况下,(def)将被转换为类似于( Haskell类型符号)的函数。

代码语言:javascript
复制
class Default a where def :: (a -> r) -> r

现在我们看到,我们可以检查延拓函数,以便了解它所期望的参数类型的信息,然后将其分派出去。

最后,如果有足够的宏观魔法,这是可以做到的.但到目前为止,要比在Clojure之上实现Haskell样式的类型系统要少得多。类型化Clojure可能是这方面的一个很好的模型,但它是显式设计的,这样Clojure的语义就不会受到推断类型的影响。这正是在返回类型多态中发生的情况,所以在类型化Clojure中这显然是不可能的。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22740178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档