2017-02-22 8 views
0

piece of Scala code at aws-scala by Atlassianでは、次の行を見つけることができます閲覧時:この@@演算子はscalazで定義されていますか?

type QueueURL = String @@ QueueURL.Marker 

私はスカラ座に新しいですが、私は間違っているかもしれませんが、@@(アットマークダブル)標準内蔵のように見えるしていません。 Scala演算子で指定します。また、注意深い読者はそれがscalaz「ライブラリからインポート見つける:

import scalaz.{ Tag, @@ } 

@@は何をしますか?それはなぜ使用されていますか?コメントで述べたように

actual definition is

いくつかのヒントがあります
type @@[A, T] = A 

+0

'https:// github.com/scalaz/scalaz'には言及していないようです。 –

+1

[ここ](https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/Tag.scala#L99)で定義されています。 –

答えて

2

タグのアイデアは、しばしばraw LongIntなどをどこからでも使用したくないということです。あなたのコードでそれらを使用したいのですが、それらを渡したくありません

def fetchUsers(numberOfUsers: Int, offset: Int): Seq[User] 

ここでは、引数の順序を入れ替えていないことを確認するために、名前付きパラメータを使用する必要があります。さらに、間違った順序で間違っていると誤解するかもしれません。

override def fetchUsers(offset: Int, numberOfUsers: Int): Seq[User] 

両方の引数に異なるタイプを使用できないようにするには、次のようにします。 1つの方法は、それはAnyValでケースクラスを使用することです - あなたがいくつかのルールに従っている場合、それはコンパイラによってプリミティブに最適化されています。タグは、いくつかの一般的な型(必ずしもプリミティブではないかもしれない)のために新しい型を導入する代わりの方法です。 @@は、あなたが気付いたように、

type @@[A, T] = A 

と定義されています。だからあなたは、新しいタイプを定義することができます。

@@[String, QueueURL.Marker] 

が、Scalaは私たちがタイプに中置構文を使用できるようにするためとして、私たちもそれを書くことができます:あなたは依存性の注入を行う場合には特に便利です

String @@ QueueURL.Marker 

例えばMacwire - 引数は型だけに基づいて取得されるため、注入可能な値ごとに区別される型を持つ必要があります(Macwireは独自のバージョンの@@を実装しています。同じ目的)。

aws-scalaコードを見ると、最初のプロパティを実現したいと思っています。一般的なタイプ(たとえばString)の異なる用途を区別し、コンパイラを使って間違いがないかどうかを確認できます。

0

タグ付けにより、新しいタイプの作成が容易になります。 @@記号を使用して、既存の型を別の型として「タグ付け」します(つまり、新しい型を作成します)。だからString @@ Textは "Text tagged"と読み替えるべきです。それがなぜ使われているのか分かりません。

+0

「タグ付け」とはどういう意味ですか?ラッピングのように - 'Option'と同じように?(型の観点から) –

+0

@GrzegorzOledzkiタグ付けとは、型に特別な意味を与えることを意味します。 – ZhekaKozlov

関連する問題