4

我对编程很陌生,我被要求将 3 个 haskell 函数转换为 python 作为练习。这 3 个函数是相连的,因为其中一个函数的输出用作下一个函数的输入,以此类推。

我得到了haskell函数的作用,但我不知道如何开始转换它们!

这是haskell代码:

factorial :: Int -> Int
factorial n = product (down n)

product :: [Int] -> Int
product [] = 1
product (a:as) = a * product as

down :: Int -> [Int]
down 0 = []
down n = n : down (n-1)

这是我转换它的尝试:

class function:
    def down(self):
        if self.n == 0:
            self.lista = []
        else:
            self.lista = range(self.n, 0, -1)

    def product(self):
        for x in self.lista:
            if x == []:
                self.product = 1
            if x != []:
                for i in self.lista:
                    self.product = i * self.product

    def factorial(self):
        self.n = int(raw_input("n="))

        self.fact = self.product(self.down(self.n))

        print self.fact
        raw_input()

c = function()
c.factorial()

好吧,首先我相信这不是haskell代码的“直接转换”。不过那没关系,但是第二,它不起作用。

这种缺乏编程背景正在杀死我......有人可以帮我解决这个问题吗?

非常感谢!

编辑:

这个问题的重点是将haskell完全转换为python。我自己做了一个精简版,这是练习的下一步^^

4

2 回答 2

7

首先,抛弃class包装——这不是必需的。

直接的 Python 翻译将类似于:

# factorial :: Int -> Int
def factorial(n):
    return product(down(n))

# product :: [Int] -> Int
def product(arr):
    if len(arr) == 0: return 1
    a, ar = arr[0], arr[1:]
    return a * product(ar)

# down :: Int -> [Int]
def down(n):
    if n == 0: return []
    return [n] + down(n - 1)

但是这里的递归风格不是很 Pythonic。下一个练习:用迭代、列表推导或调用reduce(如果在 Python2 上)替换递归。

于 2012-11-01T17:58:29.197 回答
4

如果您想编写惯用的 Python,请避免递归。

down(n)拼写为range(n, 0, -1)。如果您想要惰性语义,请使用xrange它,这将更接近 Haskell 的精神。

product(lst)reduce(operator.mul, lst, 1)。(只是拼出循环会更惯用,但这更短。)

从那里开始应该很明显如何转换factorial.

于 2012-11-01T17:53:42.603 回答