簡體   English   中英

Scala 類型參數

[英]Scala Type Parameter with Either

class OptionLikeMatcher[F[_], T, U](typeName: String, toOption: F[T] => Option[U]) extends Matcher[F[T]] { ... }
case class RightMatcher[T]() extends OptionLikeMatcher[({type l[a]=Either[_, a]})#l, T, T]("Right", (_:Either[Any, T]).right.toOption)
case class LeftMatcher[T]() extends OptionLikeMatcher[({type l[a]=Either[a, _]})#l, T, T]("Left", (_:Either[T, Any]).left.toOption)

有人可以用類型參數解釋他們試圖在這里實現什么嗎? 當用於RightMatcherLeftMatcher時, toOption: F[T] => Option[U]參數有什么類型?

它來自 Scala Specs2 庫。

讓我們首先在這里解決最復雜的類型構造函數:

({type l[a]=Either[_, a]})#l

是編碼類型 lambdas的原始方式。 它可以更簡潔地寫成

Either[_, ?]

與 kind-projector 或 as

[X] =>> Either[_, X]

在 Scala 3. 它基本上只是選擇Either的右側參數作為相關參數,並將左側參數替換為通配符。


現在, OptionLikeMatcher的三個類型參數是:

  • F[_] - 被匹配事物的類型構造函數; 預計它的行為“有點類似” Option ,即應該有某種方法可以從中獲取Option
  • T是插入F類型構造函數的類型; F[T]一起給出了匹配的類型。
  • U可以被認為是T的“輕微擾動”版本; 它捕獲與T基本相同的信息,但在將F[T]轉換為Option[U]時允許一些受控的草率(否則,如果需要F[T] => Option[T] ,那實際上是就像要求一個非常嚴格的結構,稱為自然變換F ~> Option ,在這種情況下可能過於嚴格)。

將它們放在一起給出了RightMatcher

  • F[A] = Either[_, A] - 即選擇Either的右參數,忽略左參數
  • RightMatcher中的T綁定到OptionLikeMatcher中的T
  • OptionLikeMatcher中的U也綁定到RightMatcher中的T ,即此處不使用“輕微擾動” T的可能性, OptionLikeMatcher中的TU都由相同類型實例化。

因此, toOption中的RightMatcher具有類型Either[_, T] => Option[T] (_:Either[Any, T]).right.toOption符合Either[_, T] => Option[T] ,因為Any出現在 Either 內的協變 position 中,並且Either Either[Any, T]出現在function 類型內的逆變 position,因此Either[Any, T] => Option[T]Either[_, T] => Option[T]的子類型,因為它的輸入類型更嚴格,而且它可以在需要Either[_, T] => Option[T]的任何地方使用。


話雖這么說,我找不到任何不屬於F[T]形狀的F應用程序(在OptionLikeMatcherOptionLikeChekedMatcher中都沒有),因此它們似乎將輸入類型拆分為類型構造函數F和類型參數T ,稍后僅將它們用作不可分割的單元F[T] 也許這是在從一些更復雜的構造重構之后遺留下來的。

toOption: F[T] => Option[U]參數用於RightMatcherLeftMatcher時有什么類型

也許具體的演練會有所幫助。 讓我們考慮RightMatcher[Int]() ,我們將類型參數T實例化為Int 這給了我們

F = ({type l[a]=Either[_, a]})#l
T = Int
U = T = Int

並將上述類型實例插入

toOption: F[T] => Option[U]

我們得到

toOption: (({type l[a]=Either[_, a]})#l)[Int] => Option[Int]

這簡化為

toOption: Either[_, Int] => Option[Int]

讓我們對LeftMatcher[String]()再做一次練習。 我們有

F = ({type l[a]=Either[a, _]})#l
T = String
U = T = String

並將上述類型實例插入

toOption: F[T] => Option[U]

我們得到

toOption: (({type l[a]=Either[a, _]})#l)[String] => Option[String]

這簡化為

toOption: Either[String, _] => Option[String]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM