Я работаю над реализацией алгоритма UCT в Haskell, который требует значительного объема данных.Не вдаваясь в подробности, это алгоритм моделирования, в котором на каждом «шаге» выбирается листовой узел в дереве поиска на основе некоторых статистических свойств, на этом листе создается новый дочерний узел, а статистика соответствуетобновлен новый лист и все его предки.
Учитывая все это жонглирование, я не настолько умен, чтобы выяснить, как сделать все дерево поиска хорошей неизменной структурой данных - la Okasaki .Вместо этого я немного поигрался с монадой ST
, создавая структуры, состоящие из изменяемых STRef
s.Придуманный пример (не связанный с UCT):
import Control.Monad
import Control.Monad.ST
import Data.STRef
data STRefPair s a b = STRefPair { left :: STRef s a, right :: STRef s b }
mkStRefPair :: a -> b -> ST s (STRefPair s a b)
mkStRefPair a b = do
a' <- newSTRef a
b' <- newSTRef b
return $ STRefPair a' b'
derp :: (Num a, Num b) => STRefPair s a b -> ST s ()
derp p = do
modifySTRef (left p) (\x -> x + 1)
modifySTRef (right p) (\x -> x - 1)
herp :: (Num a, Num b) => (a, b)
herp = runST $ do
p <- mkStRefPair 0 0
replicateM_ 10 $ derp p
a <- readSTRef $ left p
b <- readSTRef $ right p
return (a, b)
main = print herp -- should print (10, -10)
Очевидно, что этот конкретный пример будет гораздо проще написать без использования ST
, но, надеюсь, понятно, куда я иду с этим ... если ядолжны были применить этот стиль к моему варианту использования UCT, это неправильно?
Кто-то задавал подобный вопрос здесь пару лет назад, но я думаю, что мой вопрос немногоразные ... У меня нет проблем с использованием монад для инкапсуляции изменяемого состояния, когда это уместно, но это то, что "когда уместно", получает меня.Я беспокоюсь, что преждевременно возвращаюсь к объектно-ориентированному мышлению, где у меня есть куча объектов с геттерами и сеттерами.Не совсем идиоматичный Haskell ...
С другой стороны, если является разумным стилем кодирования для некоторого набора проблем, я предполагаю, что мой вопрос звучит так: есть ли известные способысохранить этот вид кода читабельным и обслуживаемым?Я в некотором роде отрешен от всех явных операций чтения и записи, и особенно от того, что мне приходится переводить из моих STRef
структур внутри монады ST
в изоморфные, но неизменные структуры снаружи.