A "major new release" from Oleg Kiselyov and Ralf LÃ¤mmel:

In a first phase, we demonstrate how far we can get with object-oriented functional programming, if we restrict ourselves to plain Haskell~98. In the second and major phase, we systematically substantiate that Haskell~98, with some common extensions, supports all the conventional OO features plus more advanced ones, including first-class lexically scoped classes, implicitly polymorphic classes, flexible multiple inheritance, safe downcasts and safe co-variant arguments. Haskell indeed can support width and depth, structural and nominal subtyping. We address the particular challenge to preserve Haskell's type inference even for objects and object-operating functions. Advanced type inference is a strength of Haskell that is worth preserving. Many of the features we get "for free": the type system of Haskell turns out to be a great help and a guide rather than a hindrance.

## Comment viewing options

### seems cool

I gave the paper a loose read last night, and, overall, I'm impressed. But, having objects locked up in the IO monad wouldn't be my personal cup of tea.

### does Haskell98 needs extensions to support OO?

Haskell98 can easily support the major concepts of OO, inheritance, encapsulation and message passing. Lambda functions can be used as interfaces. For example:

module Test where
foo1 :: Integer -> Integer -> Integer
foo1 p = \x -> x * p

foo2 :: Integer -> Integer -> Integer
foo2 p = \x -> x + p

foo1_msg = foo1 100
foo2_msg = foo2 200

foo_list = [foo1_msg , foo2_msg]


In the above example, we can see two 'constructor' functions 'foo1' and 'foo2' that create two interfaces of the same type but with different implementation: 'foo1' does a multiplication, while 'foo2' does an addition. An object can easily be represented as a collection of functions.

### How well Haskell98 can encode objects

axilmar wrote:

An object can easily be represented as a collection of
functions.

Yes, of course. One should point out that these functions (methods)
generally have different interfaces, so that collection must be a
record rather than a list. But records in Haskell98 are not overtly
extensible, and exhibit no record polymorphism. Implementing
inheritance then becomes a challenge -- how can you take a record Foo,
derive an extended record Bar, and still be able to pass Bar (which is
of a different type!) to a function that takes Foo. Open recursion
(calls to `self' that derived objects can interpose upon) is another
challenge. That challenges are surmountable. Section 3 of our paper
lists all, to the best of our knowledge, approaches to
encoding of objects in Haskell98, along with their strong and weak
points.