Bạn chưa thực sự thu gọn bất kỳ thứ gì ở đó. Bạn vẫn đang chạy các IO; bạn chỉ không nắm bắt được các giá trị.
Ngoài ra, đơn nguyên IO chuẩn không xác định filter
(hoặc withFilter
), vì vậy bạn không thể sử dụng các nhân viên bảo vệ để hiểu.
Bây giờ, nếu bạn muốn chỉ là những gì bạn đã nói (giống logic, chỉ DRY hơn), bạn luôn có thể gán một biến tạm thời trong cho sự hiểu biết:
for {
a <- io
b <- shortCircuit(io, a == 1)
continue = b.map(_ == 1).getOrElse(false)
c <- shortCircuit(io, continue)
d <- shortCircuit(io, continue)
e <- shortCircuit(io, continue)
} yield …
Nhưng nếu bạn thực sự muốn ngắn -circuit, bạn sẽ phải phá vỡ các trường hợp trong một số cách. Dưới đây là một khả năng, giả sử bạn chỉ muốn để đóng gói tất cả mọi thứ vào một mảng nên kiểu trả về là đơn giản, và IO
đối tượng bạn đồng hành của bạn có áp dụng phương pháp mà bạn có thể sử dụng để tạo ra một cái gì đó mà chỉ trả về một giá trị:
io.flatMap(a =>
if (a == 1) IO(() => Array(a))
else io.flatMap(b =>
if (b == 1) IO(() => Array(a,b))
else for {
c <- io
d <- io
e <- io
} yield Array(a,b,c,d,e)
)
)
Nếu các kiểu trả về của bạn phức tạp hơn, bạn có thể phải làm việc chăm chỉ hơn với việc chỉ định các kiểu.
FWIW, điều đáng chú ý là hình phạt mà bạn phải trả để giữ mọi thứ được bọc trong monads; mà không có, cùng một logic sẽ được (ví dụ):
io() match {
case 1 => Array(1)
case a => io() match {
case 1 => Array(a, 1)
case b => Array(a, b, io(), io(), io())
}
}
Và nếu bạn cho phép trở về, bạn nhận được:
val a = io()
if (a == 1) return Array(a)
val b = io()
if (b == 1) return Array(a, b)
Array(a, b, io(), io(), io())
Cũng có thể về nguyên tắc để trang trí các đơn nguyên với các phương pháp bổ sung mà giúp IO một chút, nhưng tiêu chuẩn withFilter
sẽ không hoạt động, do đó bạn sẽ không thể sử dụng đường cú pháp để hiểu.
Bạn có cần các giá trị của 'a',' b', 'c', v.v. hay bạn chỉ quan tâm đến các hiệu ứng? 'OptionT [IO,?]' Loại âm thanh giống như những gì bạn đang tìm kiếm, nhưng nó sẽ chỉ cung cấp cho bạn một 'None' nếu nó ngắn mạch. –
Tôi cần các giá trị này: làm điều kiện cho đoản mạch và cũng trong điều khoản lợi nhuận. –
io có tác dụng phụ, do đó phương thức chạy có thể trả về một giá trị khác sau mỗi cuộc gọi. –