首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Haskell到functional

从Haskell到functional
EN

Stack Overflow用户
提问于 2014-08-13 18:42:17
回答 2查看 294关注 0票数 4

我想把一些Haskell代码翻译成Python。Haskell类/实例如下所示:

代码语言:javascript
复制
{-# LANGUAGE MultiParamTypeClasses #-}

module MyModule where

class Example a b where
    doSomething :: a -> b -> Bool 
    doSomethingElse :: a -> b -> Int

instance Example Int Int where
    doSomething a b = (a + b * 2) > 5
    doSomethingElse a b = a - b * 4

Python中是否有一种方法来近似Haskell类/实例构造?什么是最不让人讨厌的方式来把它翻译成Python呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-13 18:58:47

这在Python中并没有真正的模拟,但是您可以伪造它:

代码语言:javascript
复制
def int_int_doSomething(a, b):
    return (a + b * 2) > 5


def int_int_doSomethingElse(a, b):
    return a - b * 4


Example = {}
Example[(int, int)] = (int_int_doSomething, int_int_doSomethingElse)


def doSomething(a, b):
    types = type(a), type(b)
    return Example[types][0](a, b)


def doSomethingElse(a, b):
    types = type(a), type(b)
    return Example[types][1](a, b)

您所要做的就是为您希望拥有的每个类型组合向Example添加新值。您甚至可以在doSomethingdoSomethingElse中添加一些额外的错误处理,或者其他一些方法来使其更容易。另一种方法是创建一个对象,该对象跟踪所有这些信息,并允许您以一种更受管理的方式向映射中添加新类型,但它只是在我已经展示的基础上进行了更多的簿记。

请记住,Haskell也是这样做的,除非检查是在编译时执行的。Typeclasses实际上不过是对类型进行字典查找,以选择要插入到计算中的适当函数。Haskell只是在编译时为您自动完成此操作,而不必像在Python中那样自己管理它。

要添加簿记,您可以执行如下操作,将其保存在自己的模块中,然后它将(默认情况下)导出__all__中的符号。这使得事情看起来更像Haskell版本:

代码语言:javascript
复制
class _Example(object):
    def __init__(self, doSomething, doSomethingElse):
        self.doSomething     = doSomething
        self.doSomethingElse = doSomethingElse

ExampleStore = {}

def register(type1, type2, instance):
    ExampleStore[(type1, type2)] = instance

def doSomething(a, b):
    types = type(a), type(b)
    return ExampleStore[types].doSomething(a, b)

def doSomethingElse(a, b):
    types = type(a), type(b)
    return ExampleStore[types].doSomethingElse(a, b)

def Example(type1, type2, doSomething, doSomethingElse):
    register(type1, type2, _Example(doSomething, doSomethingElse))

__all__ = [
    'doSomethingElse',
    'doSomethingElse',
    'Example'
]

然后,您可以创建类似的实例

代码语言:javascript
复制
Example(int, int,
    doSomething=lambda a, b: (a + b * 2) > 5,
    doSomethingElse=lambda a, b: a - b * 4
)

看起来就像哈斯克尔。

票数 4
EN

Stack Overflow用户

发布于 2014-08-13 18:52:44

Python中没有参数类型,因为它是动态类型的。classesinstances之间的区别在Python中也很清楚,但是由于classes本身就是“活动对象”,所以使用上的区别有时可能有点模糊……

对于您的情况,经典的实现可能如下所示:

代码语言:javascript
复制
#you don't really need this base class, it's just for documenting purposes
class Example:
    def doSomething(self, a, b):
        raise "Not Implemented"
    def doSomethingElse(self, a, b):
        raise "Not Implemented"

class ConcreteClass(Example):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def doSomething(self, a, b):
        return (a + b * self.x) > self.y
    def doSomethingElse(self, a, b):
        return a - b * self.z

 instance = ConcreteClass((2, 5, 4)

但我个人不喜欢那种复杂的风格,所以你可以选择一些更轻巧的东西,比如:

代码语言:javascript
复制
 from collections import namedtuple
 Example = namedtuple('Example', 'doSomething doSomethingElse')
 instance = Example((lambda a, b: (a + b * 2) > 5),
                    (lambda a, b: a - b *4 ))

当然,依赖鸭子打字,通常“让它崩溃”。缺乏类型安全应通过广泛的单元测试来弥补。

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

https://stackoverflow.com/questions/25293776

复制
相关文章

相似问题

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