Действие Haskell IO в `StateT a STM b`

Я хочу запустить randomIO внутри своего StateT a STM b, но получаю эту ошибку:

Expected type: StateT Session STM Float
  Actual type: IO Float

поэтому я пытаюсь выполнить lift из Control.Monad.Trans.Class (реэкспортированного модулем State's Strict):

Expected type: StateT Session STM Float
  Actual type: StateT Session IO Float

что ближе, но не совсем там. Я не могу liftIO, потому что нет экземпляра MonadIO для STM.

Как я могу скомпилировать это, чтобы я мог запустить randomIO внутри STM внутри моего StateT?


person Alex    schedule 10.08.2019    source источник
comment
Ну, преобразователь Monad оборачивает STM Float, а не IO Float.   -  person Willem Van Onsem    schedule 10.08.2019
comment
Вы не можете запускать действия ввода-вывода внутри STM, даже randomIO. Вам нужно найти обходной путь, например предварительно сгенерировать ваши случайные числа перед входом в STM или передать состояние RNG в STM.   -  person chi    schedule 10.08.2019
comment
Вы можете использовать unsafeIOToSTM, но, как следует из названия: это небезопасно, и поэтому лучше этого не делать.   -  person Willem Van Onsem    schedule 10.08.2019
comment
связанные: mail.haskell.org/pipermail/haskell-cafe/ 2007 – январь/   -  person Willem Van Onsem    schedule 10.08.2019
comment
@WillemVanOnsem, в некоторых случаях это может быть нормально. Если выбранное случайное число не влияет на вероятность успешной транзакции, то все должно быть в порядке. Я бы сказал, что это повлияет на это, тогда это изменит эффективное распределение, которое может быть или не быть приемлемым. Тем не менее, генерация случайных чисел, вероятно, занимает больше времени, чем вы действительно хотите потратить на транзакцию STM.   -  person dfeuer    schedule 11.08.2019
comment
Учитывая, что я передаю список из пакета random, каков эффект лени в этом сценарии, когда транзакция STM извлекает значение? Опасно ли проходить через преобразователь?   -  person Alex    schedule 12.08.2019


Ответы (1)


Согласно комментариям, я пытался сделать что-то глупое. Вместо этого я передал список случайных Float, которые мне нужны, для моей функции, используя randomRs (0.0, 1.0) g.

person Alex    schedule 10.08.2019