让我们说我在Java中有这样的东西:
class A {
int v;
public A(int v) {
this.v = v;
}
public int a() {
return v;
}
}
class B extends A {
public B(int v) {
super(v);
}
@Override
public int a() {
return super.a() + 5;
}
}
我怎样才能在Haskell中做类似的事情?我对类型类有一个非常基本的了解。我想在虚拟方法中使用虚拟方法来获得ArrayList<A>
个对象(或者只是Haskell中的[A]
),这些方法将继承自超类。
答案 0 :(得分:1)
有一种&#34;模式&#34;这样工作:
data Animal m = Animal {
makeSound :: m ()
}
cat = Animal {
makeSound = print "Meow!"
}
dog = Animal {
makeSound = print "Woof!"
}
cow = Animal {
makeSound = print "Moo!"
}
animals = [cat, cat, dog, cow]
main = mapM_ makeSound animals
使用这种模式,您可以做一些或多或少的疯狂事情,例如:
import Data.Maybe
data I a = I {
f :: a,
sup :: Maybe (I a)
}
mkA = I { f = 10, sup = Nothing }
mkB = let a = mkA in I {
f = 5 + f a,
sup = Just a
}
ls = [mkA, mkB, fromJust $ sup mkB]
main = mapM_ (print . f) ls
此模式还可用于实现像工厂一样的功能,如:
import Data.IORef
data Storage m a = Storage {
putData :: String -> m (),
readData :: m String
}
fileStorage path = Storage {
putData = \s -> writeFile path s,
readData = readFile path
}
inMemStorage ref = Storage {
putData = \s -> writeIORef ref s,
readData = readIORef ref
}
readStorage storage = readData storage
chooseStorage "file" = return $ fileStorage "tmp.txt"
chooseStorage "mem" = do
r <- newIORef ""
return $ inMemStorage r
main = do
storage <- chooseStorage "mem"
putData storage "hi there"
txt <- readData storage
print txt
基本上,您定义了一个以函数为成员的数据类型,然后定义&#34; constructors&#34; (它们只是常规函数)返回该数据类型的实例。