Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell to Python: multiple-functions conversion issue

I am pretty new to programming and I was asked to convert 3 haskell functions into python as a practice exercise. The 3 functions are connected, since output of one is used as the input of the next one and so on.

I get what the haskell functions do, but I have no idea how to start converting them!

This is the haskell code:

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)

And this was my try of converting it:

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()

Well, first I believe this isn't a 'direct conversion' of the haskell code. That would be okay though, but second, it doesn't work.

This lack of programming background is killing me...can anyone help me with this problem?

Thanks a lot!

Edit:

The point of this issue is to exactly convert the haskell into python. I did a stripped version of it myself, it was the next step in the exercise ^^

like image 731
Edward Coelho Avatar asked Dec 20 '22 14:12

Edward Coelho


2 Answers

First off, ditch the class wrapper - that's not needed.

A straight Python translation would be something like:

# 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)

But the recursive style is not very Pythonic here. Next exercise: replace recursion with iteration, list comprehensions, or calls to reduce (if on Python2).

like image 161
Deestan Avatar answered Jan 11 '23 10:01

Deestan


If you want to write idiomatic Python, avoid recursion.

down(n) is spelled as range(n, 0, -1). Use xrange if you want lazy semantics, which would be closer to the spirit of Haskell.

product(lst) is reduce(operator.mul, lst, 1). (It would be more idiomatic to just spell out the loop, but this is shorter.)

From there on it should be obvious how to convert factorial.

like image 20
user4815162342 Avatar answered Jan 11 '23 10:01

user4815162342