Сторона «ввода» монады ввода-вывода - это столько же, сколько и вход.Если вы используете строку ввода, факт того, что вы использовали этот вход , передается извне, а также служит для записи в качестве нечистого состояния (т. Е. Вы больше не потребляете ту же строку позже);это такая же операция вывода, как и putStrLn
.Кроме того, операции ввода должны быть упорядочены относительно операций вывода;это опять-таки ограничивает, насколько вы можете разделить их.
Если вы хотите получить чистую монаду только для чтения, вам, вероятно, следует использовать вместо нее монаду reader .
При этомВы, кажется, немного смущены тем, что может сделать объединение монад.В то время как вы действительно можете объединить две монады (при условии, что одна является преобразователем монад) и получить некоторую гибридную семантику, вы должны иметь возможность запустить результат .То есть, даже если бы вы могли определить IT (OT Identity) r
, как вы его запустите?В этом случае у вас нет корневой монады IO
, поэтому main должна быть чистой функцией.Что означало бы, что у вас будет main = runIdentity . runOT . runIT $ ...
.Что бессмысленно, поскольку вы получаете нечистые эффекты из чистого контекста.
Другими словами, тип монады IO должен быть фиксированным.Это не может быть выбранный пользователем преобразованный тип, потому что его тип прибит в main
.Конечно, вы можете позвонить это I (O Identity)
, но вы ничего не получите;O (I Identity)
будет бесполезным типом, как I []
или O Maybe
, потому что вы никогда не сможете запустить ни один из них.
Конечно, если IO
оставить какосновной IO
тип монады, вы можете определить такие подпрограммы, как:
runI :: I Identity r -> IO r
Это работает, но опять же, вы не можете иметь ничего под этим, я очень легко монаду, и вы не получаете много от этогосложность.В любом случае, что бы означало , если преобразовать монаду Output в базовую монаду List, в любом случае?