以动态语言键入类

jhe*_*dus 8 lisp python clojure

我必须承认,我只掌握Python的基本知识,目前正在学习Haskell.

我想知道类型类的概念是否存在/在Python或Clojure(或其他一些动态强类型语言)中有意义?

换句话说,如果我有一个函数名,f那么根据运行时参数,f将调用另一个函数实现(就像==属于EqHaskell中类型类的类型的函数).这样的概念是否存在于动态语言中,例如Clojure/Python?

Thu*_*ail 5

多种方法似乎可以解决Clojure的问题。例如,让我们定义一个plus函数,该函数添加数字但将其他字符串的字符串表示形式连接起来。

(defmulti plus (fn [& xs] (every? number? xs)))

(defmethod plus true [& xs] (apply + xs))
(defmethod plus false [& xs] (apply str xs))

(plus 1 8) ;9
(plus 1 \8) ;"18"
Run Code Online (Sandbox Code Playgroud)

多重方法是函数((ifn? plus)is true),因此也就象您希望的那样是一流的:

(let [z (partial plus 5)] (z \3)) ;"53"
Run Code Online (Sandbox Code Playgroud)

  • 多重方法是真正的功能(“(ifn?plus)”是“ true”)。“ ifn”会测试某些东西是否可以作为函数调用,而很少使用的“ fn”会测试是否使用“ fn”定义了东西。 (2认同)

ama*_*loy 4

您可以使用 clojure 中的多方法或协议,或者使用 python 中的简单成员函数(类方法)来非常接近这一点。不过,haskell 中的每一项都缺少一个重要功能:返回类型多态性。

编译器知道您“期望”函数返回什么类型,并且可以相应地分派到不同的实现。这意味着使用相同参数调用的相同函数可以执行完全不同的操作,具体取决于对其返回值执行的操作。例如:

Prelude> read "[5,6,7]" :: [Int]
[5,6,7]
Prelude> read "[5,6,7]" :: [Double]
[5.0,6.0,7.0]
Run Code Online (Sandbox Code Playgroud)

同样,您甚至可以拥有多态常量,每个类型类实例都有不同的值:

Prelude Data.Word> (minBound, minBound, minBound) :: (Int, Bool, Word8)
(-9223372036854775808,False,0)
Run Code Online (Sandbox Code Playgroud)

您实际上无法用动态语言来做到这一点,因为没有类型推断。您可以通过传递代表“我想要的结果类型”的对象来稍微伪造它,并将它们用作您的调度程序,但实际上并不相同。