在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吗?
如果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)