问题描述
我试图通过文章 Haskell/Existentially quantified types 掌握 Haskell 中存在类型的概念。乍一看,这个概念似乎很清楚,有点类似于面向对象语言中的泛型。主要的例子有一个叫做“异构列表”的东西,定义如下:
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
我对“异构列表”有不同的看法,例如 Shapeless in Scala。但在这里,它只是一个包含在仅添加类型约束的存在类型中的项目列表。它的元素的确切类型并没有体现在它的类型签名中,我们唯一知道的是它们都符合类型约束。
在面向对象的语言中,写这样的东西似乎很自然(Java 中的例子)。这是一个无处不在的用例,我不需要创建包装器类型来处理所有实现某个接口的对象列表。 animals
列表有一个泛型类型 List<Vocal>
,所以我可以假设它的元素都符合这个 Vocal
接口:
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);
我注意到存在类型仅作为语言扩展可用,并且在大多数“基础”Haskell 书籍或教程中都没有描述它们,所以我的建议是这是一个非常高级的语言功能。
我的问题是,为什么?在具有泛型的语言中看起来基本的东西(构造和使用其类型实现一些接口并以多态方式访问它们的对象列表),在 Haskell 中需要语言扩展、自定义语法并创建额外的包装器类型?如果不使用存在类型,就没有办法实现这样的目标,或者只是没有基本级别的用例?
或者也许我只是混淆了概念,存在类型和泛型意味着完全不同的东西。请帮我理解一下。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)