-1
class Person:
  def __init(fname, lname):
    this.fname = fname
    this.lname = lname

  def greet():
    print "Good day, " + fname + ", " + lname

if __name__ == "__main__":
  p = Person("saravana", "kumar")
  p.greet()

outputs,

hello saravana, kumar

How can this simple python code be ported to haskell? I am keen on learning oops concept like initializing object states and accessing them through methods in the haskell language.

  • 1
    Also see this nice answer from @leftaroundbot: http://stackoverflow.com/a/20188103/1651941 – Sibi May 09 '15 at 17:29
  • 1
    I would recommend against learning any new language in this way, and strongly so when different paradigms are involved. Thinking in one paradigm and then translating into another can (and _will_) generate very unidiomatic code, at best. – chi May 09 '15 at 19:53

2 Answers2

10

First don't think with an OOPS mind, that will just not work out with Haskell and would cause you pain.

Try to think the problem in terms of the Haskell way,

data Person = Person { fname :: String, lname :: String } deriving Show

greet :: Person -> String
greet p = "Good day, " ++ fname p ++ ", " ++ lname p

Demo in ghci:

λ> greet $ Person "Erik" "Meijer"
"Good day, Erik, Meijer"

See how simple was that ?

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
Sibi
  • 47,472
  • 16
  • 95
  • 163
  • 1
    It's worth noting that this is still remarkably similar to the original Python code :) – chepner May 09 '15 at 17:47
  • 2
    @chepner Yes, but mind the warning in the first line of this answer. The code may look similar, but there are some profound differences. For one, the original Python code _prints_ a string, while the Haskell code _returns_ it. – chi May 09 '15 at 19:56
  • Yes, but even something like `greet :: Person -> IO ()`, `greet p = putStr $ "Good day, " ...` is still pretty easy to understand what it's doing. (Even you don't entirely understand what `IO ()` means or the exact syntax.) – chepner May 10 '15 at 20:50
4

lets try to port it to Haskell literally..

data Person = Person { fname :: String
                     , lname :: String 
                     }   

In your Python code, any Person object can perform an action greet() that does some IO which gets translated to Haskell as:

greet :: Person -> IO ()
greet person = putStrLn $ (fname person) ++ " " ++ (lname person)

then you would write main as:

main :: IO ()
main = greet $ Person "Ben" "Tennyson"

Now, what's wrong in doing it that way ? - Purity.

Haskell idioms provides ways to keep pure and impure code separate. lets try to do it Haskell way...

Create a Category Human whose elements could be a Person/Student/Employee or whatever who all share a common action greet()

class Human a where
  greet :: a -> String

We can also create a Show instance for our Person type:

instance Show Person where
  show person = (fname person) ++ " " ++ (lname person)

then create a Human instance for Person implementing greet() action:

instance Human Person where
  greet person = "Hello, " ++ (show person)

main :: IO ()
main = putStrLn . greet $ Person "Ben" "Tennyson"

-- λ main
-- Hello, Ben Tennyson
Shanthakumar
  • 757
  • 6
  • 23