简体   繁体   English

Haskell替代虚拟方法和方法继承

[英]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.

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