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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21739190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 06:04:21  来源:igfitidea点击:

Can someone explain to me what the Shapeless library is for?

scalashapeless

提问by loyalflow

Can someone explain to me in simple terms what the Shapeless library is for?

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

Scala has generics and inheritance functionality so I'm a bit confused what Shapeless is for.

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

Maybe a use case to clarify things would be helpful.

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

回答by Kevin Wright

It's a little hard to explain, as shapeless has a wide range of features; I'd probably find it easier to "explain, in simple terms, what variables are for". You definitely want to start with the feature overview.

这有点难以解释,因为 shapeless 具有广泛的功能;我可能会发现“用简单的术语解释变量的用途”更容易。您肯定想从功能概述开始。

Broadly speaking, shapeless is about programming with types. Doing things at compile-time that would more commonly be done at runtime, keeping precise track of the type of each element in a list, being able to translate from tuples to HLists to case classes, creating polymorphic functions (as opposed to methods), etc.

从广义上讲,shapeless 是关于使用类型进行编程。在编译时做一些在运行时更常见的事情,精确跟踪列表中每个元素的类型,能够将元组转换为 HList 再到 case 类,创建多态函数(与方法相反),等等。

A typical usage scenario would go something like:

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

  • Read a bunch of values from somewhere into a List
  • perform a type-safe cast of that Listinto an HList
  • map over that HListwith a polymorphic function that e.g. normalises values
  • convert the 3rd element (which is statically known to be an Int) into a 0-padded string
  • construct a case class using values from the HList
  • 从某处读取一堆值到一个 List
  • 将其执行类型安全List转换为HList
  • HList使用多态函数映射它,例如标准化值
  • 将第三个元素(静态已知为 an Int)转换为 0 填充字符串
  • 使用来自 HList 的值构造一个案例类

For reference, an HListwill have a precise type, such as Int :: String :: Boolean :: HNil(yes, that really isa single type) where everything is pinned down and the size is fixed. So you either need to know at compile time exactly what will be going into your HList, or you need the type-safe cast.

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

If you take the tailof such an HList, you get a String :: Boolean :: HNil, and a compile-time guarantee that the head of this will be a String. Prepending a value to the head will similarly preserve all types involved.

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

Shapeless also comes with the Generictype class, allowing you to use HList operations on tuples and case classes as well.

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

The other features I tend to use are:

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

  • Coproducts, which allow you to statically type a value as being e.g. "a String, Doubleor Int, but nothing else" (much like Either, but not limited to just two possibilities)

  • Lenses, which simplify working with nested case classes.

  • Coproducts,它允许您静态键入一个值,例如“a String, Doubleor Int,但没有别的”(很像Either,但不仅限于两种可能性)

  • Lenses,这简化了嵌套案例类的工作。

回答by wheaties

Looking at an HListis something that might seem baffling until you try to work with types and delegate or switch on types. Take a look at the following:

HList您尝试使用类型并委托或打开类型之前,查看 an可能看起来令人困惑。看看以下内容:

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

What is the type of myListhere? If you were to inspect it, you'd see it was of type List[Any]. That's not very helpful. What's even less helpful is if I tried to use the following PartialFunction[Any]to mapover it:

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

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

At runtime, this might throw a MatchErrorbecause I haven't actually told you what type fredis. It could be of type Fred.

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

With an HListyou can know right at compile time if you've failed to capture one of the types of that list. In the above, if I had defined myList = 1 :: 2 :: "3" :: fred :: HNilwhen I accessed the 3rd element, it's type would be Stringand this would be known at compile time.

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

As @KevinWright states, there's more to it than that with Shapeless but HListis one of the defining features of the library.

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

回答by Seth Tisue

Everything in Shapeless has two things in common:

Shapeless 中的所有内容都有两个共同点:

First, it isn't in the Scala standard library, but arguably should be. Therefore, asking what Shapeless is for is a bit like asking with the Scala standard library is for! It's for everything. It's a grab bag.

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

(but it isn't a totally arbitrary grab bag, because:)

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

Second, everything in Shapeless provides increased checking and safety at compile time. Nothing in Shapeless (that I can think of?) actually “does” anything at runtime. All of the interesting action happens when your code is compiled. The goal is always increased confidence that if your code compiles at all, it won't crash or do the wrong thing at runtime. (Hence this notable quip: https://twitter.com/mergeconflict/status/304090286659866624)

其次,Shapeless 中的所有内容都在编译时提供了增强的检查和安全性。Shapeless(我能想到的?)中没有任何东西在运行时“做”任何事情。所有有趣的操作都在编译代码时发生。目标始终是增加信心,即如果您的代码完全编译,它就不会在运行时崩溃或做错事。(因此这个值得注意的俏皮话:https: //twitter.com/mergeconflict/status/304090286659866624

There is a nice introduction to what type-level programming is all about, with links to further resources, at https://stackoverflow.com/a/4443972/86485.

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