简体   繁体   中英

Haskell alternative to virtual methods and method inheritance

Let's say I have something like this in 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? 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM