Tôi đang cố gắng triển khai vùng chứa cho kết quả phù hợp (như trong thể thao) để tôi có thể tạo kết quả phù hợp giữa người chiến thắng của các trận đấu khác. Khái niệm này là gần với những gì một monads trong tương lai là vì nó chứa một giá trị được xác định, và cũng gần với một nhà nước monad vì nó ẩn thay đổi trạng thái. Chủ yếu là một người ăn xin về chủ đề tôi đã thực hiện một phiên bản ban đầu trong scala đó là chắc chắn không thể thay đổi. Tôi đã thêm một phương thức có được mà tôi không chắc chắn là một ý tưởng tốt, và cho đến nay cách duy nhất để tạo ra một giá trị sẽ là Unknown(null)
mà không phải là thanh lịch như tôi hy vọng. Bạn nghĩ tôi có thể làm gì để cải thiện thiết kế này?cách triển khai khái niệm tương lai/trạng thái này dưới dạng đơn nguyên trong scala
case class Unknown[T](t : T) {
private var value : Option[T] = Option(t)
private var applicatives: List[T => Unit] = Nil
def set(t: T) {
if (known) {
value = Option(t)
applicatives.foreach(f => f(t))
applicatives = Nil
} else {
throw new IllegalStateException
}
}
def get : T = value.get
def apply(f: T => Unit) = value match {
case Some(x) => f(x);
case None => applicatives ::= f
}
def known = value == None
}
CẬP NHẬT: một ví dụ sử dụng của việc thực hiện hiện sau
case class Match(val home: Unknown[Team], val visit: Unknown[Team], val result: Unknown[(Int, Int)]) {
val winner: Unknown[Team] = Unknown(null)
val loser: Unknown[Team] = Unknown(null)
result.apply(result => {
if (result._1 > result._2) {
home.apply(t => winner.set(t))
visit.apply(t => loser.set(t))
} else {
home.apply(t => loser.set(t))
visit.apply(t => winner.set(t))
}
})
}
Và một đoạn thử nghiệm:
val definedUnplayedMatch = Match(Unknown(Team("A")), Unknown(Team("B")), Unknown(null));
val definedPlayedMatch = Match(Unknown(Team("D")), Unknown(Team("E")), Unknown((1,0)));
val undefinedUnplayedMatch = Match(Unknown(null), Unknown(null), Unknown(null));
definedUnplayedMatch.winner.apply(undefinedUnplayedMatch.home.set(_))
definedPlayedMatch.winner.apply(undefinedUnplayedMatch.visit.set(_))
undefinedUnplayedMatch.result.set((3,1))
definedUnplayedMatch.result.set((2,4))
undefinedUnplayedMatch.winner.get must be equalTo(Team("B"));
undefinedUnplayedMatch.loser.get must be equalTo(Team("D"));
CẬP NHẬT - HIỆN IDEA: tôi đã không có nhiều thời gian để giải quyết vấn đề này vì laptop của tôi bị hỏng, nhưng tôi sẽ rất hữu ích khi viết đơn nguyên Tôi có cho đến nay đối với những người quan tâm:
sealed abstract class Determine[+A] {
def map[B](f: A => B): Determine[B]
def flatMap[B](f: A => Determine[B]): Determine[B]
def filter(p: A => Boolean): Determine[A]
def foreach(b: A => Unit): Unit
}
final case class Known[+A](value: A) extends Determine[A] {
def map[B](f: A => B): Determine[B] = Known(f(value))
def flatMap[B](f: A => Determine[B]): Determine[B] = f(value)
def filter(p: A => Boolean): Determine[A] = if (p(value)) this else Unknown
def foreach(b: A => Unit): Unit = b(value)
}
final case class TBD[A](definer:() => A) extends Determine[A] {
private var value: A = _
def map[B](f: A => B): Determine[B] = {
def newDefiner(): B = {
f(cachedDefiner())
}
TBD[B](newDefiner)
}
def flatMap[B](f: A => Determine[B]): Determine[B] = {
f(cachedDefiner())
}
def filter(p: A => Boolean): Determine[A] = {
if (p(cachedDefiner()))
this
else
Unknown
}
def foreach(b: A => Unit): Unit = {
b(cachedDefiner())
}
private def cachedDefiner(): A = {
if (value == null)
value = definer()
value
}
}
case object Unknown extends Determine[Nothing] {
def map[B](f: Nothing => B): Determine[B] = this
def flatMap[B](f: Nothing => Determine[B]): Determine[B] = this
def filter(p: Nothing => Boolean): Determine[Nothing] = this
def foreach(b: Nothing => Unit): Unit = {}
}
Tôi đã thoát khỏi những bộ & có được và bây giờ là lớp TBD nhận thay vì một chức năng mà sẽ xác định cung cấp giá trị hoặc null nếu vẫn không xác định. Ý tưởng này hoạt động tốt cho phương pháp bản đồ, nhưng phần còn lại của các phương pháp có lỗi tinh tế.
Không đáng lo ngại về việc triển khai, bạn có thể đưa ra một số ví dụ về cách bạn * sử dụng * một đơn nguyên như vậy bằng cách sử dụng 'flatMap' hoặc' for' comprehensions không? Việc triển khai của bạn hiện thiếu phương thức 'flatMap' để xác định ngữ nghĩa trên đơn vị của bạn. – huynhjl
Tôi đã cập nhật câu hỏi bằng cách sử dụng thử nghiệm tôi đang cung cấp cho nó ngay bây giờ. Tôi nhận ra rằng việc triển khai của tôi quá vụng về để tận dụng lợi thế của sự hiểu biết vào lúc này, về cơ bản nó là một cổng của một mô hình quan sát trong Java thiếu đường cú pháp. – ilcavero
Nó không phải là rất rõ ràng từ ví dụ của bạn những gì bạn đang cố gắng để thực hiện trong việc đưa ra các [A] không rõ monad. Bạn có thể cho chúng tôi biết thêm một chút về ứng dụng sẽ sử dụng thư viện này không? – dyross