Monady IO - raczej chyba się w Scali nie używa, bo nie ma sensnu. IO ma sens w językach funkcyjnych i raczej jest koniecznością, a nie "wygodą".
W czystem jezyku trudno by było bez monady IO zrobić nawet prosty kalkulator BMI, bo w w takim np. kodzie:
//siakis pseudojezyk
println("podaj wage")
int waga = readLine()
println("podaj wzrost" )
int wzrost = readLine()
...
Kompilator mógłby stwierdzić, że przecież dwa razy wywołujemy readLine, bez argumentów, więc na pewno wynik jest ten sam (bo języki czyste zakładają, że funkcja wywołana z tymi samymi argumentami zwraca ten sam wynik). .. więc zrobiłby tylko jedno wywołanie i podstawił ten sam wynik w obu miejscach.
Do du..y z takim kalkulatorem!
Nie mówiąc o tym, że mógłby sobie przemieszać kolejność println i najpier poprosić w wpis z klawiatury, a dopiero potem zrobić stosowny println.
Z monadą IO jakkolwiek, readLine i inne funkcje wejścia/wyjścia przyjmują dodatkowy parametr IO i zwracaja wynik w postaci zmodyfikowanego "stanu" IO.
IO<Void> startIO = ..
IO<Void> p1 = println(startIO, "podajWagę")
IO<String> waga = readLine(p1)
IO<Void> p2 = println(waga, "podajWzrost")
IO<String> wzrost = readLine(p2)
Po czymś takim, kompilator nie ma jak "uprościć/ zoptymalizować" i musi zrobić podane operacje IO w podanej przez nas kolejności.
Troszke takie przekazywanie sobie berła między wywołaniami. Technicznie sam obiekt IO - jest pustym obiektem, znacznikiem.
W pewnym sensie Monada IO to tylko głupia sztuczka, ratująca tyłek w językach czysto funkcyjnych.
W jezykach imperatywnych kompilator i tak nie ma pola do popisu i nie może za wiele sam przestawiać (bo kto wie co by się wywaliło), dlatego cała ta zabawa w berło IO nie ma sensu.
A może raczej, nie jest niezbędna. Może jest jakiś sens "deklarowania" tego, że bawimy się w IO... ale ja sensownego zysku na razie nie widze.