Tôi đã xem một video gần đây về cách bạn có thể tìm ra đơn nguyên IO, cuộc trò chuyện diễn ra trong scala. Tôi thực sự tự hỏi những gì các điểm có chức năng trả lại IO [A] trong số họ. Các biểu thức lambda được bọc trong đối tượng IO là những đột biến và tại một số điểm cao hơn sự thay đổi chúng phải được quan sát, ý tôi là đã được thực hiện, để một cái gì đó xảy ra. Bạn không chỉ đẩy vấn đề lên cao hơn cái cây ở nơi khác?Scala IO monad: điểm là gì?
Lợi ích duy nhất tôi có thể thấy là nó cho phép đánh giá lười biếng, theo nghĩa là nếu bạn không gọi hoạt động unsafePerformIO không có tác dụng phụ xảy ra. Ngoài ra tôi đoán các phần khác của chương trình có thể sử dụng/chia sẻ mã và deciede khi nó muốn các tác dụng phụ xảy ra.
Tôi đã tự hỏi nếu điều này là tất cả? Có lợi thế trong testability? Tôi giả sử không phải là bạn sẽ phải quan sát các hiệu ứng mà loại phủ nhận điều này. Nếu bạn đã sử dụng các đặc điểm/giao diện, bạn có thể kiểm soát các phụ thuộc nhưng không phải khi các hiệu ứng diễn ra trên các phụ thuộc này.
Tôi tổng hợp ví dụ sau trong mã.
case class IO[+A](val ra:() => A){
def unsafePerformIO() : A = ra();
def map[B](f: A => B) : IO[B] = IO[B](() => f(unsafePerformIO()))
def flatMap[B](f: A => IO[B]) : IO[B] = {
IO(() => f(ra()).unsafePerformIO())
}
}
case class Person(age: Int, name: String)
object Runner {
def getOlderPerson(p1: Person,p2:Person) : Person =
if(p1.age > p2.age)
p1
else
p2
def printOlder(p1: Person, p2: Person): IO[Unit] = {
IO(() => println(getOlderPerson(p1,p2))).map(x => println("Next"))
}
def printPerson(p:Person) = IO(() => {
println(p)
p
})
def main(args: Array[String]): Unit = {
val result = printPerson(Person(31,"Blair")).flatMap(a => printPerson(Person(23,"Tom"))
.flatMap(b => printOlder(a,b)))
result.unsafePerformIO()
}
}
Bạn có thể xem hiệu ứng được hoãn lại cho đến khi chính tôi đoán là điều tuyệt vời. Tôi đã nghĩ ra điều này sau khi cảm nhận điều này từ video.
Việc triển khai của tôi có đúng không và sự hiểu biết của tôi có chính xác hay không.
Tôi cũng tự hỏi liệu có nên lấy milage hay không, nó phải được kết hợp với ValidationMonad, như trong ValidationMonad [IO [Person]] để chúng ta có thể đoản mạch khi ngoại lệ xảy ra? Suy nghĩ xin vui lòng.
Blair
Cảm ơn. Câu trả lời tuyệt vời tôi sẽ xem xét những ý tưởng đó tối nay. –
Bạn có đoạn mã với các lớp con và nhập các lớp học không? –
Xem các trang trình bày của Runar mà Drexin liên kết đến, cụ thể là công cụ 'ConsoleIO'. Nó thể hiện sự tách biệt khai báo những hành động IO tồn tại ('đối tượng trường hợp GetLine ...', 'trường hợp lớp PutLine ...') từ định nghĩa về những gì có thể xảy ra nếu bạn chạy các hành động đó ('đối tượng ẩn ConsoleEffect .. .'). Nhưng lưu ý có những thứ khác trong đó quá; nó không phải là mã tối thiểu thể hiện _only_ những gì tôi đã nói. –