谁能给我解释一下无形图书馆是干什么用的?

有人能简单解释一下无形图书馆是干什么用的吗?

Scala 有泛型和继承功能,所以我有点搞不懂 Shapless 是干什么的。

也许用一个用例来澄清事情会有所帮助。

13616 次浏览

这有点难以解释,因为无形具有广泛的特性; 我可能会发现“用简单的术语解释变量是用来做什么的”更容易一些。你肯定想从 功能概览开始。

广义地说,无形是指使用类型进行编程。在编译时完成通常在运行时完成的工作,精确跟踪列表中每个元素的类型,能够将元组转换为 HList,转换为 case 类,创建多态函数(而不是方法) ,等等。

典型的使用场景是这样的:

  • 将一组值从某处读入 List
  • 执行该 ListHList的类型安全强制转换
  • 使用多态函数映射该 HList,例如规范化值
  • 将第3个元素(静态已知为 Int)转换为0填充的字符串
  • 使用 HList 中的值构造 case 类

作为参考,一个 HList将有一个精确的类型,如 Int :: String :: Boolean :: HNil(是的,真正的 一个单一的类型) ,其中一切都固定下来,大小是固定的。因此,您要么需要在编译时确切地知道将要进入 HList 的内容,要么需要类型安全强制转换。

如果获取这样一个 HList 的 tail,就会得到一个 String :: Boolean :: HNil,并且在编译时保证其头部是 String。类似地,在头部预设一个值将保留所有涉及的类型。

Shapless 还附带了 Generic类型类,允许您对元组和 case 类使用 HList 操作。

我倾向于使用的其他特性是:

  • Coproducts ,它允许您静态地键入一个值,例如“ a StringDoubleInt,但没有其他值”(非常类似于 Either,但不限于两种可能性)

  • Lenses ,它简化了使用嵌套案例类的工作。

查看 HList可能是一件令人困惑的事情,直到您尝试处理类型并委托或打开类型。请看以下内容:

val myList = 1 :: 2 :: "3" :: fred :: Nil

这里的 myList是什么类型的?如果你检查一下,你会发现它是 List[Any]型的。这可没什么帮助。如果我试着用下面的 PartialFunction[Any]map来代替它,那就更没有帮助了:

myList.map{
case x: Int => x
case x: String => Int.parseInt(x)
}

在运行时,这可能抛出一个 MatchError,因为我实际上还没有告诉您 fred是什么类型。可能是 Fred型。

使用 HList,您可以在编译时知道是否未能捕获该列表的一种类型。在上面的例子中,如果我在访问第3个元素时定义了 myList = 1 :: 2 :: "3" :: fred :: HNil,那么它的类型应该是 String,这在编译时就会知道。

正如@KevinWright 所说,Shapless 不仅仅是这样,而且 HList是该库的一个重要特性。

《无形》里的所有东西都有两个共同点:

首先,它不在 Scala 标准库中,但可以说应该在。因此,询问 Shapless 的用途有点像询问 Scala 标准库的用途!是 谢谢你所做的一切。这是个抢包。

(但这不是一个完全随意的抓包,因为:)

其次,Shapless 中的所有内容都增加了检查和安全 在编译时。《无形》里没有(我能想到的?)实际上在运行时“做”任何事情。编译代码时会发生所有有趣的操作。目标总是增加信心,即如果您的代码编译,它不会崩溃或在运行时做错误的事情。(因此,这个著名的俏皮话: https://twitter.com/mergeconflict/status/304090286659866624“做 Miles Sabin 在运行时存在吗?”)

https://stackoverflow.com/a/4443972/86485上有一个关于类型级编程的很好的介绍,以及指向更多资源的链接。