Не смотри на слово чистое, это плохое слово, оно плохо описывает то, что в ФП происходит.
Идея в том, что если у тебя раньше была функция
def count() -> int:
return get_counter()
Она не была сылочно прозрачной. Т.к если ты все вызовы count() заменишь на её возвращаемое значение, то ты получишь какую-то константу везде и потеряешь поведение программы.
Теперь ты сделал так:
def count_io() -> IO[int]:
return lambda real_world: get_counter()
Теперь если ты эту функцию заменишь на её значение, то поведение не изменится, т.к. сама фyнкция count_io() ничего не делает с эффектами, она просто возвращает замыкание.
Соотвественно она ссылочно прозрачная.