Haskell替代虚方法和方法继承

时间:2015-11-08 23:48:13

标签: haskell inheritance

让我们说我在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]),这些方法将继承自超类。

1 个答案:

答案 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; (它们只是常规函数)返回该数据类型的实例。