W rzeczywistości niczego tam nie zwieszałeś. W dalszym ciągu korzystasz z OI; po prostu nie przechwytujesz wartości.
Ponadto, standardowa monada IO nie definiuje filter
(lub withFilter
), więc nie można używać strażników w swoim rozumieniu.
Teraz, jeśli chcesz po prostu to, co pan powiedział (tę samą logikę, tylko bardziej suchy), zawsze można przypisać zmienną tymczasową w do zrozumienia:
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 …
Ale jeśli rzeczywiście chcesz krótki -circuit, będziesz musiał rozdzielić przypadki w jakiś sposób. Oto jedna z możliwości, zakładając, że po prostu chce się pakować wszystko do tablicy tak typ zwracany jest proste, a IO
towarzysz obiekt ma sposobu stosowania, które można wykorzystać, aby stworzyć coś, że po prostu zwraca wartość:
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)
)
)
Jeśli twoje typy zwrotu są bardziej skomplikowane, być może będziesz musiał pracować ciężej z określaniem typów.
FWIW, warto zauważyć karę, którą płacisz za trzymanie rzeczy zapakowanych w monady; bez, ta sama logika byłaby (na przykład):
io() match {
case 1 => Array(1)
case a => io() match {
case 1 => Array(a, 1)
case b => Array(a, b, io(), io(), io())
}
}
A jeśli pozwalają zwrotów dostaniesz:
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())
Jest to również możliwe w zasadzie do dekoracji Monada IO z dodatkowych metod, które pomagają się nieco, ale standardowy withFilter
nie będzie działał, więc nie będziesz w stanie użyć cukru syntaktycznego dla zrozumienia.
Czy potrzebujesz wartości 'a',' b', 'c' itd., Czy też zależy Ci tylko na efektach? 'OptionT [IO,?]' Rodzaj dźwięków jak to, czego szukasz, ale to po prostu dałoby ci 'Brak' jeśli to zwarcie. –
Potrzebuję tych wartości: jako warunek dla zwarcia, a także w klauzuli yield. –
io ma efekt uboczny, więc metoda run może zwracać inną wartość po każdym wywołaniu. –