Python可以实现依赖类型吗?

时间:2017-04-08 09:10:31

标签: python types type-systems idris

Idris 中依赖类型的简单演示是Vector,其类型取决于它的值。

我们可以在Python中定义Type Hints。

from typing import List

def append(a: List[int], b: List[int]) -> List[int]:
    return a + b

print(append([1, 2], [1, 3, 4]))

那么,我们可以实现一个类型Vect,可以使用如下:

def append(a: Vect[m,t], b: Vect[n,t]) -> Vect[(m+n),t]:
    return a + b

mn是自然数字,t是任何类型。

2 个答案:

答案 0 :(得分:3)

,但这是 hacky (而且很难正确解决所有问题)。首先,在对对象进行更改时,您需要修改对象的类型。

来自docs

“对象的类型确定对象支持的操作(例如,“它是否有长度吗?”),并且还定义了该类型对象的可能值。type()函数返回对象的类型(即对象本身)。就像其身份一样,对象的类型也是不可更改的。[1]“

但在[1]的脚注中:

“ [1]在某些情况下 在某些受控条件下的对象类型。通常不是 不过,这是一个好主意,因为它可能导致某些非常奇怪的行为 如果处理不当。”

要更改对象的类型,您需要将对象的__class__属性设置为其他类。这是一个简单的示例,其中包含两种与值相关的整数类型:

class Integer:                                                                           
    def __init__(self, value):                                                           
        self.value = int(value)                                                          
        self.set_class()                                                                 

    def set_class(self):                                                                 
        if self.value < 10:                                                              
            self.__class__ = LessThanTen                                                 
        else:                                                                            
            self.__class__ = TenOrMore                                                   

    def add(self, value):                                                                
        self.value += int(value)                                                         
        self.set_class()                                                                 

class TenOrMore(Integer):                                                                
    def __init__(self):                                                                  
        pass                                                                             
        raise ValueError("Use Integer()")                                                

class LessThanTen(Integer):                                                              
    def __init__(self):                                                                  
        raise ValueError("Use Integer()")

然后可以对它们执行标准操作,并根据它们的新值对其进行更改:

>>> from dependent import Integer, TenOrMore, LessThanTen
>>> a = Integer(5)
>>> print(a.value, type(a))
5 <class 'dependent.LessThanTen'>
>>> a.add(10)
>>> print(a.value, type(a))
15 <class 'dependent.TenOrMore'>

此方法需要预先对类进行硬编码。尽管可能需要一些生成体操来确保所有内容都生活在相同的范围内(例如顶级词典和类生成器函数),但是可以动态生成类。但是,我认为当前的类型提示系统不支持这种动态生成的类。

答案 1 :(得分:0)

我创建了一个库,该库使您可以将类型视为一流,而无需像David所说的那样预先进行硬编码。当然,它也很hacky,重写功能以使用类型提示。

https://github.com/vixrant/python-type-theory