Я строю код, чтобы получить понимание, на самом деле Solitaire solver. У меня есть простая реализация грубой силы, в которой используется государственная монада, на самом деле просто для того, чтобы доказать, что я могу ее использовать (она только подсчитывает количество вычислений каждого движения). Но теперь я хочу использовать Unboxed Mutable массивы для записи посещенных плат и, таким образом, ярлык оценки путей, когда я достигаю позиции доски, которая уже была посещена по другому пути. Кажется, что монашка ST не позволяет мне вступать в неявное состояние, но я должен использовать ST (или IO), чтобы получить доступ к массиву Mutable. Поэтому мне кажется, что я должен объединить два состояния Monads - State для потока состояния (на самом деле включающего Mutable array), а другой (ST) для получения функций Mutable array.Как я могу совместить монаду монахов и монадию штата (или эквивалент)?
- Это право?
- И если да, есть ли лучшая альтернатива, чем комбинация Data.Array.ST/Control.Monad.ST/Control.Monad.ST и mtl?
- Если я иду по этому маршруту, имеет значение, какой заказ я собираю ST и State?
- Должен ли я рассмотреть возможность прокатки собственной одиночной Монады на основе любого или обоих ST или состояний, чтобы избежать использования монадных трансформаторов?
Если я следую этому пути, как передать переменную состояния (которая включает в себя изменяемый массив)? Когда я прочитал ваше предложение, я бы создал STREF во главе моей рекурсивной функции и явно прочитал и написал его, убедившись, что STRef всегда отображается в функциях, определенных в функции верхнего уровня? В отличие от использования State, где это подразумевается, когда я использую monadic bind - могу ли я добиться того же самого, что и в ST? Если да, то как? – hdb3
Вы можете определить 'type STState s st = ReaderT (STRef s st) (ST s)', а затем выполнить вычисления 'STState' с помощью' runSTState sts = newSTRef initState >> = runReaderT sts'. Этот подход изоморфен простому прохождению «STRef» вручную, но, возможно, более эстетично. Конечно, в этот момент вам может быть лучше, просто используя «StateT st (ST s)». –
AFAIK, STM используется для _avoid_ любой синхронизации потоков. – user3974391