web-dev-qa-db-ja.com

誰かが私にShapelessライブラリの目的を説明できますか?

誰かが私に簡単な言葉でShapelessライブラリの目的を説明できますか?

Scalaにはジェネリックと継承の機能があるため、Shapelessの目的が少し混乱しています。

たぶん、物事を明確にするためのユースケースが役立つでしょう。

69
loyalflow

Shapelessにはさまざまな機能があるため、説明するのは少し難しいです。 「変数の目的を簡単に説明する」方が簡単だと思います。 機能の概要 から始めたいと思います。

大まかに言うと、shapelessは型を使ったプログラミングに関するものです。実行時により一般的に行われるコンパイル時の処理、リスト内の各要素の型の正確な追跡、タプルからHListへのケースクラスへの変換、メソッドではなくポリモーフィック関数の作成、等.

典型的な使用シナリオは次のようになります。

  • どこかからListに値の束を読み込む
  • そのListからHListへの型保証キャストを実行します
  • そのHListを、たとえば値を正規化します
  • 3番目の要素(Intであることが静的に知られている)を0で埋められた文字列に変換します
  • hListの値を使用してケースクラスを構築する

参考までに、 HList には、Int :: String :: Boolean :: HNilなどの正確な型があります(はい、本当にis単一のタイプ)すべてが固定され、サイズが固定されています。そのため、コンパイル時にHListに何が入るかを正確に知る必要があるか、タイプセーフキャストが必要です。

このようなHListのtailを取得すると、String :: Boolean :: HNilが得られ、コンパイル時の保証でこのヘッドがStringになることが保証されます。同様に、値を先頭に追加すると、関係するすべてのタイプが保持されます。

Shapelessには Generic タイプクラスも付属しているため、タプルやケースクラスでもHList操作を使用できます。

私が使用する傾向がある他の機能は次のとおりです。

  • Coproducts 。これにより、値を静的に入力できます。 「StringDouble、またはIntであるが、他には何もありません」(Eitherに似ていますが、2つの可能性に限定されません)

  • Lenses 。ネストされたケースクラスでの作業を簡素化します。

47
Kevin Wright

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を使用すると、そのリストのタイプの1つをキャプチャできなかった場合、コンパイル時にすぐに知ることができます。上記で、3番目の要素にアクセスしたときにmyList = 1 :: 2 :: "3" :: fred :: HNilを定義していた場合、そのタイプはStringになり、これはコンパイル時にわかります。

@KevinWrightが述べているように、Shapelessにはそれ以上のものがありますが、HListはライブラリの定義機能の1つです。

32
wheaties

Shapelessのすべてには、2つの共通点があります。

まず、これはScala標準ライブラリにはありませんが、間違いなくあるはずです。したがって、Shapelessの目的を尋ねるのは、Scala標準ライブラリは、!のすべてであり、グラブバッグです。

(ただし、完全にtotally意的なグラブバッグではありません。理由は次のとおりです。)

次に、Shapelessのすべてが、コンパイル時のチェックと安全性の向上を提供します。 Shapelessには何もありません(私が考えることはできますか?)実行時に実際に何かを「行う」ことはありません。興味深いアクションはすべて、コードのコンパイル時に発生します。目標は常に、コードがまったくコンパイルされても、実行時にクラッシュしたり間違った動作をしたりしないという自信を高めることです。 (したがって、この注目すべきクイップ: https://Twitter.com/mergeconflict/status/304090286659866624

https://stackoverflow.com/a/4443972/86485 に、さらに詳細なリソースへのリンクを含む、タイプレベルプログラミングの概要が記載されています。

20
Seth Tisue