有人可以向我解释Shapeless库的用途吗?[关闭]


70

有人可以简单地向我解释Shapeless库的用途吗?

Scala具有泛型和继承功能,因此我对Shapeless的用途感到有些困惑。

也许用例来说明问题会有所帮助。

Answers:


50

很难解释,因为无形状具有多种功能。我可能会发现“以简单的方式解释什么是变量”更为容易。您肯定要从功能概述开始。

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

典型的使用场景如下:

  • 从某处读取一堆值 List
  • 对它执行类型安全的List转换HList
  • HList用多态函数在其上进行映射,例如对值进行归一化
  • 将第3个元素(静态称为Int)转换为0填充的字符串
  • 使用HList中的值构造一个案例类

作为参考,anHList将具有精确的类型,例如Int :: String :: Boolean :: HNil(是的,这实际上单个类型),其中所有内容固定,大小固定。因此,您要么需要在编译时确切地知道将要进入HList的内容,要么需要类型安全的强制转换。

如果tail使用HList的,则将获得String :: Boolean :: HNil,并在编译时保证其头将是String。在值前面加上一个值将类似地保留所有涉及的类型。

Shapeless也随Generic类型类一起提供,允许您在元组和案例类上使用HList操作。

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

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

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


32

HList尝试使用类型并委派或启用类型之前,看一个似乎有些困惑。看一下以下内容:

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

这里是什么类型myList?如果要检查它,您会发现它是type List[Any]。那不是很有帮助。如果我尝试使用以下内容PartialFunction[Any]来解决问题,map则更没有帮助:

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

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

使用a,HList您可以在编译时知道是否无法捕获该列表的类型之一。在上面的代码中,如果我定义了myList = 1 :: 2 :: "3" :: fred :: HNil访问第三个元素的时间,则其类型为,String并且在编译时就可以知道。

正如@KevinWright所言,它比Shapeless的功能更多,但这HList是该库的定义功能之一。


20

Shapeless中的一切都有两个共同点:

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

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

其次,Shapeless中的所有内容在编译时都提供了增强的检查和安全性。Shapeless(我能想到的)没有任何东西在运行时真正“做什么”。当编译代码时,所有有趣的动作都会发生。我们的目标始终是提高人们的信心,即如果您的代码完全可以编译,它就不会崩溃或在运行时做错事情。(因此,这个著名的技巧:https : //twitter.com/mergeconflict/status/304090286659866624

https://stackoverflow.com/a/4443972/86485上可以很好地介绍类型级编程的全部内容,并提供指向更多资源的链接。


3
“首先,它不在Scala标准库中,但可以说应该存在。” 如果发生这种情况,我会逃跑...然后尖叫。
JayZee

@JayZee为什么这么说?
stsatlantis

1
让我尝试一下比较...如果斯卡拉类型的安全性是素食主义,而无形的素食主义者!在我看来,它增加了一层额外的类型安全性,使scalac编译器本来就很复杂的生命变得复杂。Shapeless需要更多的隐式和更多的类型类。我不是scala编译的超级专家,但是您不愿意使用shapeless所付出的代价是,编译器将面临更艰难的情况,并且围绕着shapeless(至少是我的经验)并且会变慢。我更喜欢有一堆“ isInstanceOf”,有时会碰到ClassCastException并修复,而不是依靠无形的魔法。
JayZee

还要考虑一下,即使您的IDE也不是问题,即使您的IDE也很难键入推断或尝试编译代码。
JayZee

强调“可以说”。
塞斯·提苏
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.