[英]Haskell alternative to virtual methods and method inheritance
Let's say I have something like this in Java: 假设我在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;
}
}
How could I do something similar in Haskell? 我该如何在Haskell中做类似的事情? I have a very basic understanding what typeclasses are. 我对类型类有一个非常基本的了解。 I would like to have something like ArrayList<A>
of objects (or just [A]
in Haskell) with virtual methods, which would be inherited from the superclass. 我想使用虚拟方法创建类似ArrayList<A>
的对象(或者在Haskell中只是[A]
),这些方法将从超类继承。
There's kind of a "pattern" that works like this: 有点像这样的“模式”:
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
Using this pattern you can do some more-or-less crazy things such as: 使用这种模式,您可以做一些或多或少的疯狂事情,例如:
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
This pattern can also be used to achieve "factory"-like functionality like: 此模式还可用于实现类似于“工厂”的功能,例如:
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
Basically you define a data type that has functions as its members and then define "constructors" (which are just regular functions) that return an instance of that data type. 基本上,您定义一个以函数为成员的数据类型,然后定义返回该数据类型实例的“构造函数”(只是常规函数)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.