如何在函数中返回某些类型类的类型

时间:2014-03-09 14:03:12

标签: haskell

我想通过提供一个函数来删除以下代码中的重复代码,该函数返回某个类型类的实例值(本例中为ClassA):

class ClassA a where
  f :: a -> Int
data A1 = A1 Int Int
instance ClassA A1 where
  f (A1 v1 v2) = v1 + v2
data A2 = A2 Int Int
instance ClassA A2 where
  f (A2 v1 v2) = v1 * v2

g1 :: ClassA a => a -> Int
g1 iA = f iA + 1
g2 :: ClassA a => a -> Int
g2 iA = f iA + 2

class ClassB b where
  newB :: Int -> b
  h1 :: b -> Int
  h2 :: b -> Int

data B1 = B1 A1
fromB1toA1 :: B1 -> A1
fromB1toA1 (B1 a) = a
instance ClassB B1 where
  newB v = B1 (A1 v v)
  h1 b = let a = fromB1toA1 b in g1 a -- repeative code!!
  h2 b = let a = fromB1toA1 b in g2 a -- repeative code!!

data B2 = B2 A2
fromB2toA2 :: B2 -> A2
fromB2toA2 (B2 a) = a
instance ClassB B2 where
  newB v = B2 (A2 v v)
  h1 b = let a = fromB2toA2 b in g2 a -- repeative code!!
  h2 b = let a = fromB2toA2 b in g2 a -- repeative code!!

main = do
  let a1 = A1 2 4
  let a2 = A2 2 4
  print (f a1, g1 a1, g2 a1)
  print (f a2, g1 a2, g2 a1)

  let b1 = B1 (A1 5 5)
  let b2 = B2 (A2 6 6)
  print (h1 b1, h2 b1)
  print (h1 b2, h2 b2)

  print "bye"

我试图做这样的事情,但它没有为我编译:

class ClassB b where
  newB :: Int -> b
  toClassA :: (ClassA a) => b -> a
  h1 :: b -> Int
  h1 b = let a = toClassA b in g1 a -- doesn't compile
  h2 :: b -> Int
  h2 b = let a = toClassA b in g2 a -- doesn't cimpile

data B1 = B1 A1
instance ClassB B1 where
  newB v = B1 (A1 v v)
  toClassA (B1 a) = a -- doesn't compile

data B2 = B2 A2
instance ClassB B2 where
  newB v = B2 (A2 v v)
  toClassA (B2 a) = a  -- doesn't compile

1 个答案:

答案 0 :(得分:1)

我无法找到一个足够短的足够短的例子。

但我确实发现我想描述的问题可归类为"子类型"多态性问题(en.wikipedia.org/wiki/Type_polymorphism#Subtyping)。

并且根据:haskell.org/haskellwiki/Polymorphism," Haskell不支持或至少不是本地支持的某种多态性,例如:包含多态性和子类型,在OO语言中很常见,其中一种类型的值可以作为另一种类型的值。 "

重复:Subtype polymorphism in Haskell