Я просто изучаю монады Haskell и IO. Мне интересно, почему бы это не заставить программу выводить "привет", а также "пока":
second a b = b
main = print ((second $! ((print "hi") >>= (\r -> return ()))) "bye")
Насколько я понимаю, оператор $! заставил бы первый аргумент second быть оценен, а оператору >>= нужно было бы запустить print "hi", чтобы получить от него значение и передайте его на \r -> return (), который напечатает "hi" на экране.
Что не так с моими рассуждениями?
А также, есть ли способ пропустить Haskell нельзя обмануть (кроме использования небезопасных функций) в выполнение операций ввода-вывода внутри "безопасного" кода?