Explain Type Classes in Haskell

前端 未结 6 1562
南旧
南旧 2020-12-28 10:04

I am a C++ / Java programmer and the main paradigm I happen to use in everyday programming is OOP. In some thread I read a comment that Type classes are more intuitive in na

6条回答
  •  盖世英雄少女心
    2020-12-28 10:52

    In C++/etc, "virtual methods" are dispatched according to the type of the this/self implicit argument. (The method is pointed to in a function table which the object implicitly points to)

    Type classes work differently, and can do everything that "interfaces" can and more. Let's start with a simple example of something that interfaces can't do: Haskell's Read type-class.

    ghci> -- this is a Haskell comment, like using "//" in C++
    ghci> -- and ghci is an interactive Haskell shell
    ghci> 3 + read "5" -- Haskell syntax is different, in C: 3 + read("5")
    8
    ghci> sum (read "[3, 5]") -- [3, 5] is a list containing 3 and 5
    8
    ghci> -- let us find out the type of "read"
    ghci> :t read
    read :: (Read a) => String -> a
    

    read's type is (Read a) => String -> a, which means for every type that implements the Read type-class, read can convert a String to that type. This is dispatch based on return type, impossible with "interfaces".

    This can't be done in C++ et al's approach, where the function table is retrieved from the object - here, you don't even have the relevant object until after read returns it so how could you call it?

    A key implementation difference from interfaces that allows this to happen, is that the function table isn't pointed to inside the object, it is passed separately by the compiler to the called functions.

    Additionally, in C++/etc when one defines a class they are also responsible on implementing their interfaces. This means that you can't just invent a new interface and make Int or std::vector implement it.

    In Haskell you can, and it isn't by "monkey patching" like in Ruby. Haskell has a good name-spacing scheme that means that two type classes can both have a function of the same name and a type can still implement both.

    This allows Haskell to have many simple classes like Eq (types that support equality checking), Show (types that can be printed to a String), Read (types that can be parsed from a String), Monoid (types that have a concatenation operation and an empty element) and many more, and allows for even the primitive types like Int to implement the appropriate type-classes.

    With the richness of type-classes people tend to program to more general types and then have more reusable functions and since they also have less freedom when the types are general they may even produce less bugs!

    tldr: type-classes == awesome

提交回复
热议问题