Haskell中的OOP样式继承

GEL*_*GEL 5 c# oop haskell

在C#中,我可以声明以下内容

class A {
    int Field;
}

class B : A {
    int Field2;
}

static int f(A a) { return a.Field; }
static int f(B b) { return a.Field + b.Field2; }

static void Main(string[] args) {
    A a = new A() { Field = 1 };
    A b = new B() { Field = 1, Field = 2};

    Console.WriteLine(f(a) + f(b));
}
Run Code Online (Sandbox Code Playgroud)

在Haskell中,我会输入上面的内容

data A = A { field :: Int } | B { field :: Int, field2 :: Int }

f :: A -> Int
f (A a) = a
f (B a b) = a + b

main :: IO()
main = do putStrLn $ show (f(a) + f(b))
    where a = A 1
          b = B 1 2
Run Code Online (Sandbox Code Playgroud)

我不喜欢Haskell对应的是我必须field在数据定义中重复两次A(这变得更加无聊,A因为需要的字段数增加了B).在Haskell中有一种更简洁的方式来编写(有点类似于C#方式)B的子类A吗?

sep*_*p2k 6

如果A有很多字段,那么一个可能有意义的设计是为A和B提供两种不同的数据类型,其中B包含A,然后使用类型类来定义f.像这样:

data A = A {field1 :: Int, field2 :: Int, ..., field9999 :: Int}
data B = B {a :: A, field10000 :: Int}

class ABC a where
    f :: a -> Int

instance ABC A where
    f a = field1 a + field101 a

instance ABC B where
    f b = f (a b) + field10000 b
Run Code Online (Sandbox Code Playgroud)