My experience with Functional Programming Languages is small. I’ve been writing small hacks for emacs lisp, such as hooks for certain modes and actions for a while, and sometimes building small tools in SBCL. Someone on Internet has recommended me an interesting book about Haskell called "Real World Haskell", that may be read on-line. I’ve been reading the book in my free time, and playing with the Haskell syntax, building small functions and playing with data type. So the result of those games is a small program that I want to share with you.
First, I was playing with some business data types, and I’ve defined some data types for Haskell:
data Role = Undefined
| Researcher
| Engineer
| Scientist
deriving (Eq, Show)
data Person = Person {
pid :: Int
, name :: String
, born :: Int
} deriving (Eq, Show)
data Employee = Employee {
who :: Person
, role :: [ Role ]
} deriving (Eq, Show)
data Company = Company {
cName :: String
, employee :: [ Employee ]
} deriving (Eq, Show)
For me, data type signatures matters. I prefer strongly typed languages, instead of the ambiguity of some others. Then I’ve defined some variable to string conversion functions, so I can display the structure of the Company data type.
asStringPerson :: (Person) -> String
asStringPerson (p) = ( name p )
++ " [" ++ ( show ( born p ) ) ++ "]"
asStringEmployee :: (Employee) -> String
asStringEmployee (e) = "\n" ++ ( asStringPerson ( who e ) )
++ " as " ++ ( show ( role e ) )
asStringEmployeeList :: ( [ Employee ] ) -> String
asStringEmployeeList (el) = do let s :: String
s = ""
foldr (\i a -> ( a ++ ( asStringEmployee i ) ) ) s el
asStringCompany :: (Company) -> String
asStringCompany (c) = ( cName c ) ++ " has employeed "
++ ( asStringEmployeeList ( employee c ) )
The magic of foldr that turns the el parameter of type [ Employee ] into a string is like the magic on the semantics of (map #’(lambda x) ()) in Lisp. But looking at the documentation of Hakell, it has support for a wide variety of map-work-alike functions ;)
main :: IO ()
main = do let someone1P :: Person
someone1P = Person {
pid = 1
, name = "Juan Perez"
, born = 1927
}
someone1E :: Employee
someone1E = Employee {
who = someone1P
, role = [ Researcher, Scientist ]
}
someone2P :: Person
someone2P = Person {
pid = 2
, name = "Perico Palotez"
, born = 1929
}
someone2E :: Employee
someone2E = Employee {
who = someone2P
, role = [ Engineer, Scientist ]
}
aiCompany :: Company
aiCompany = Company {
cName = "IA Company"
, employee = [ someone1E, someone2E ]
}
putStrLn ( asStringCompany aiCompany )
The main program instantiates a group of Employee data types and puts them in the aiCompany as Company data type is. If you take a little bit of attention on the code, I’m worried of some significant details, such as naming and signing data types properly, since I prefer that nomenclature for readability.
I shall continue learning it. I think that the code is elegant, mainly since I can use monadic features, which reduces the lines of code and make the program more legible too. You can download the source code for this toy program here.



