2012-11-01 95 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 –