当前位置: 首页 > 知识库问答 >
问题:

Haskell中的存在类型和其他语言中的泛型

孔宇
2023-03-14
data ShowBox = forall s. Show s => SB s
 
heteroList :: [ShowBox]
heteroList = [SB (), SB 5, SB True]

instance Show ShowBox where
  show (SB s) = show s
 
f :: [ShowBox] -> IO ()
f xs = mapM_ print xs

main = f heteroList
interface Vocal {

    void voice();
}

class Cat implements Vocal {

    public void voice() {
        System.out.println("meow");
    }
}

class Dog implements Vocal {

    public void voice() {
        System.out.println("bark");
    }
}

var animals = Arrays.asList(new Cat(), new Dog());
animals.forEach(Vocal::voice);

或者我只是混淆了概念,存在类型和泛型意味着完全不同的东西。请帮我弄明白。

共有1个答案

夏锐藻
2023-03-14

是的,存在主义类型和泛型意味着不同的东西。存在类型可以类似于面向对象语言中的接口使用。当然,您可以在列表中放置一个,但是使用接口不需要列表或任何其他泛型类型。只要有一个vocal类型的变量来演示它的用法就足够了。

它在Haskell中没有被广泛使用,因为大多数时候并不真正需要它。

nonHeteroList :: [IO ()]
nonHeteroList = [print (), print 5, print True]

在没有任何语言扩展的情况下做同样的事情。

interface Shape {
   void Draw();
   double Area();
}

例如,可以用Haskell将其表示为,

type Shape = (IO (), Double)

然后说

circle center radius = (drawCicrle center radius, pi * radius * radius)
rectangle topLeft bottomRight = (drawRectangle topLeft bottomRight, 
           abs $ (topLeft.x-bottomRight.x) * (topLeft.y-bottomRight.y))

shapes = [circe (P 2.0 3.5) 4.2, rectangle (P 3.3 7.2) (P -2.0 3.1)]

尽管您可以用类型、类、实例和存在表示完全相同的内容

class Shape a where
  draw :: a -> IO ()
  area :: a -> Double

data ShapeBox = forall s. Shape s => SB s
instance Shape ShapeBox where
  draw (SB a) = draw a
  area (SB a) = area a

data Circle = Circle Point Double
instance Shape Circle where
  draw (Circle c r) = drawCircle c r
  area (Circle _ r) = pi * r * r

data Rectangle = Rectangle Point Point
instance Shape Rectangle where
  draw (Rectangle tl br) = drawRectangle tl br
  area (Rectangle tl br) = abs $ (tl.x - br.x) * (tl.y - br.y)

shapes = [Circle (P 2.0 3.5) 4.2, Rectangle (P 3.3 7.2) (P -2.0 3.1)]
 类似资料:
  • 问题内容: 目前,我在Java中遇到通用类问题。 我有这样的事情: 现在,我实例化了一个没有类型参数的类的对象,因为我对此没有兴趣或不知道。 问题是,尽管编译器不依赖于参数,但它不仅丢弃有关类型参数的信息,而且还丢弃有关集合(字符串)的类型的信息。 我是在做错什么,还是Java的限制?如果是这样,那为什么会有限制? 问题答案: 你做错了 如果您不知道T类型,则只需使用通配符: GenericCla

  • 这些到底有什么区别呢?我想我理解存在类型是如何工作的,它们就像OO中的基类没有向下强制转换的方法一样。通用类型有何不同?

  • Nacos社区当前仅提供了Java版本的客户端,我们将主要依靠社区的贡献来发展多语言客户端。在未来,我们将向Nacos社区用户推荐那些最被广泛使用的以及支持最好的客户端作为Nacos相应语言的官方版本。 go cpp python nodejs more ...

  • 问题内容: 我想对两个均扩展Number的相同类型的泛型参数执行操作。 可能吗?我一直习惯在泛型参数上调用方法,但使用运算符似乎存在一些问题(对于参数T,T,运算符+未定义)。 我究竟做错了什么? 编辑:我试图改善我的问题。我知道没有为Number类型定义运算符。这件事有点可悲,因为在不引入@Victor Sorokin建议的新接口的情况下执行这样的操作会很好。 但是我仍然不明白一件事:如果没有在

  • Haskell是一种纯函数式语言,其属于类标准ML(SML))模型函数语言的一种。与其他已经提过的语言不同,Haskell(或SML)编程是通过函数式进行描述,应用会通过表达式的参数对表达式做出对应的判断。通常,编程的顺序不同会导致不同的结果。这会使外部声明的值没有进行初始化。这就能看出Haskell类语言的主要优势和劣势。因为Haskell在编程时的劣势很突出,并且其复杂的类型系统,通常会让一些

  • “绑定不匹配:Team类型不是league类型 的有界参数 >的有效替代品。”