Hãy tỏa sáng một ánh sáng khác về điều này.
PartialFunction[A, B]
là đẳng cấu cho A => Option[B]
. (Trên thực tế, để có thể kiểm tra nếu nó được định nghĩa cho một A
đưa ra mà không gây ra đánh giá của B
, bạn sẽ cần A => LazyOption[B]
)
Vì vậy, nếu chúng ta có thể tìm thấy một Monoid[A => Option[B]]
chúng tôi đã chứng minh khẳng định của bạn.
Với Monoid[Z]
, chúng ta có thể hình thành Monoid[A => Z]
như sau:
implicit def readerMonoid[Z: Monoid] = new Monoid[A => Z] {
def zero = (a: A) => Monoid[Z].zero
def append(f1: A => Z, f2: => A => Z) = (a: A) => Monoid[Z].append(f1(a), f2(a))
}
Vì vậy, những gì monoid (s) làm chúng ta phải nếu chúng ta sử dụng Option[B]
như Z
của chúng tôi? Scalaz cung cấp ba. Ví dụ chính yêu cầu Semigroup[B]
.
implicit def optionMonoid[B: Semigroup] = new Monoid[Option[B]] {
def zero = None
def append(o1: Option[B], o2: => Option[B]) = o1 match {
case Some(b1) => o2 match {
case Some(b2) => Some(Semigroup[B].append(b1, b2)))
case None => Some(b1)
case None => o2 match {
case Some(b2) => Some(b2)
case None => None
}
}
}
Sử dụng này:
scala> Monoid[Option[Int]].append(Some(1), Some(2))
res9: Option[Int] = Some(3)
Nhưng đó không phải là cách duy nhất để kết hợp hai Options. Thay vì phụ thêm nội dung của hai tùy chọn trong trường hợp chúng là cả hai Some
, chúng ta có thể chỉ cần chọn đầu tiên hoặc cuối cùng của hai tùy chọn. Hai kích hoạt này, chúng tôi tạo ra một loại riêng biệt với thủ thuật được gọi là Tagged Types. Điều này tương tự với tinh thần của Haskell là newtype
.
scala> import Tags._
import Tags._
scala> Monoid[Option[Int] @@ First].append(Tag(Some(1)), Tag(Some(2)))
res10: [email protected]@[Option[Int],scalaz.Tags.First] = Some(1)
scala> Monoid[Option[Int] @@ Last].append(Tag(Some(1)), Tag(Some(2)))
res11: [email protected]@[Option[Int],scalaz.Tags.Last] = Some(2)
Option[A] @@ First
, nối thông qua nó Monoid
, sử dụng cùng một orElse
ngữ nghĩa như ví dụ của bạn.
Vì vậy, đặt này tất cả cùng nhau:
scala> Monoid[A => Option[B] @@ First]
res12: scalaz.Monoid[A => [email protected]@[Option[B],scalaz.Tags.First]] =
[email protected]
tôi giả sử bạn nhận thức được rằng 'Function1' là một monoid dưới thành phần? –
@dcsobral 'Hàm1 [A, A]', hay còn gọi là 'Endo [A] ', là. – retronym