有人可以向我解释一下Shapeless库的用途吗?

loy*_*low 70 scala shapeless

有人能用简单的语言向我解释一下Shapeless库的用途吗?

Scala具有泛型和继承功能,所以我对Shapeless的用途有点困惑.

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

Kev*_*ght 47

这有点难以解释,因为无形具有广泛的功能; 我可能会发现更容易"用简单的术语解释变量的用途".您肯定希望从功能概述开始.

从广义上讲,无形是关于类型编程.在编译时做一些事情,通常在运行时完成,保持精确跟踪列表中每个元素的类型,能够从元组转换为HLists到案例类,创建多态函数(而不是方法),等等

典型的使用场景将类似于:

  • 从一个地方读取一堆值到一个 List
  • 执行的一个类型安全的铸造ListHList
  • HList使用例如使值正常化的多态函数映射
  • 将第3个元素(静态地称为a Int)转换为0填充字符串
  • 使用HList中的值构造案例类

作为参考,一个HList将有一个精确的类型,如Int :: String :: Boolean :: HNil(是的,这确实一个单一类型的)的一切是牵制和大小是固定的.因此,您需要在编译时确切知道将要进入HList的内容,或者您​​需要类型安全的强制转换.

如果你使用tail这样一个HList,你会得到String :: Boolean :: HNil一个编译时保证,这将是一个String.将值添加到头部将同样保留所涉及的所有类型.

Shapeless还附带了Generic类型类,允许您对元组和案例类使用HList操作.

我倾向于使用的其他功能是:

  • Coproducts,这让你静态类型的值作为例如"一个String,Double或者Int,但没有别的"(很像Either,但不局限于只有两个可能性)

  • Lenses,简化了嵌套案例类的使用.


whe*_*ies 32

HList尝试使用类型和委托或切换类型之前,查看一个看起来令人困惑的东西.看看以下内容:

val myList = 1 :: 2 :: "3" :: fred :: Nil
Run Code Online (Sandbox Code Playgroud)

这是什么类型的myList?如果你要检查它,你会发现它是类型的List[Any].这不是很有帮助.更有帮助的是,如果我尝试使用以下内容PartialFunction[Any]map覆盖它:

myList.map{
  case x: Int => x
  case x: String => Int.parseInt(x)
}
Run Code Online (Sandbox Code Playgroud)

在运行时,这可能会抛出一个,MatchError因为我实际上并没有告诉你什么类型fred.它可能是类型Fred.

随着HList你就可以知道正确在编译的时候,如果你没有捕捉类型列表中的一种.在上面,如果我在myList = 1 :: 2 :: "3" :: fred :: HNil访问第3个元素时已经定义了它的类型,那么String这将在编译时知道.

正如@KevinWright所说,除了Shapeless之外,它还有更多,但它HList是该库的定义功能之一.


Set*_*sue 20

Shapeless中的所有东西都有两个共同点:

首先,它不在Scala标准库中,但可以说应该是.因此,询问Shapeless的用途有点像用Scala标准库来询问!它适用于一切.这是一个抓包.

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

其次,Shapeless中的所有内容都可以在编译时提供更高的检查和安全性.Shapeless中没有什么(我能想到的?)在运行时实际上"做"了什么.编译代码时会发生所有有趣的操作.目标始终是增加信心,如果您的代码完全编译,它将不会崩溃或在运行时做错事.(因此这个值得注意的讽刺:https://twitter.com/mergeconflict/status/304090286659866624)

通过/sf/answers/311078071/,可以很好地介绍什么类型级编程,以及更多资源的链接.

  • "首先,它不在Scala标准库中,但可以说应该是." 如果发生这种情况,我会逃跑......然后尖叫. (3认同)