2012-11-01 128 views
4

我对编程非常陌生,并被要求将3个haskell函数转换为python作为练习练习。 这3个功能是连接的,因为一个的输出被用作下一个的输入等等。Haskell to Python:多功能转换问题

我得到了什么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的准确转换为蟒。 我自己做了一个剥离版本,这是练习中的下一步^^

+0

将代码从一种您不完全理解的语言转换为另一种您不完全理解的语言是学习编程的一种可怕方式。我会建议谁给你的练习,他们让你感觉舒适的阅读和写代码在一种语言第一。 – Ben

回答

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) 

但递归的风格不是很Python的在这里。下一个练习:用迭代替换递归,列表解析或者调用reduce(如果在Python2上)。

+2

最后的练习,阅读stdlib中'math'模块的'factorial'函数:D – mgilson

+0

哦,我很惊讶这可能是多么的简单!没有想法haskell与python非常相似。非常感谢! –

+1

这段代码的问题不在于它是unpythonic(即不是惯用的Python),而是它给初学者一个Python和Haskell之间相似的错误印象。 Python的列表是连续的数组,因此获取其余成员对于长列表来说是一项昂贵的操作。换句话说,Python的'ar = arr [1:]'在CPU和内存使用方面与Haskell对首个和剩余列表元素的解包完全不同。 – user4815162342

4

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

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

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

从那里就应该很明显如何转换factorial

+0

谢谢!我真的应该使用懒惰的语义,并不知道! –

+2

如果你喜欢懒惰的语义,你会喜欢[生成器](http://www.python.org/dev/peps/pep-0255/)。 Python比人们倾向于思考的更加懒惰。 :) – user4815162342

+0

非常感谢! :D –