簡體   English   中英

Haskell替代虛擬方法和方法繼承

[英]Haskell alternative to virtual methods and method 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] ),這些方法將從超類繼承。

有點像這樣的“模式”:

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

基本上,您定義一個以函數為成員的數據類型,然后定義返回該數據類型實例的“構造函數”(只是常規函數)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM