derivingに関する考察

x::Int
x = 1

data DerivingShow = Foo Int deriving Show
y::DerivingShow
y = Foo 2

data CustomizedShow = Bar Int
instance Show CustomizedShow where
    show (Bar x) = "[Custom: " ++ show x ++ "]"

z::CustomizedShow
z = Bar 2

main = print z

これをPythonで書く。もちろんHaskellの宣言がPythonの手続きに置き換わっているもろもろの関係で「同じ内容を実装した」とは言えないことに注意。

>>> class Int(object):
    def __init__(self, v):
        self.value = v
    def show(self):
        return str(self.value)

    
>>> Int(1)
<__main__.Int object at 0x01492C90>
>>> Int(1).show()
'1'
>>> class CustomizedShow(object):
    @staticmethod
    def Bar(intValue): # data constructor
        self = CustomizedShow()
        self.value = intValue
        return self
    def show(self):
        return "[Custom: " + self.value.show() + "]"

    
>>> CustomizedShow.Bar(Int(2))
<__main__.CustomizedShow object at 0x01492D70>
>>> CustomizedShow.Bar(Int(2)).show()
'[Custom: 2]'
>>> class DerivingShow(object):
    @staticmethod
    def Foo(intValue): # data constructor
        self = DerivingShow()
        self.value = intValue
        return self

    
>>> def deriving_show(cls):
    def show(self):
        return (
            self.__class__.__name__ +
            " " + self.value.show())
    cls.show = show

    
>>> deriving_show(DerivingShow)
>>> DerivingShow.Foo(Int(3))
<__main__.DerivingShow object at 0x01492B50>
>>> DerivingShow.Foo(Int(3)).show()
'DerivingShow 3'

このPythonのコードはオブジェクトがshowメソッドを持っていることを実行前に保証はしない。
なのでShow型クラスが出てこない。Javaインターフェイス的なものがあればそれをimplementsすることで保証できるかな。
ただ、Javaインターフェイスと違って実装を持つことができる。多重継承もできる。