Я работаю над внедрением алгоритма UCT в Haskell, что требует значительного количества манипуляций с данными. Не вдаваясь в подробности, это алгоритм моделирования, где на каждом "шаге" лист node в дереве поиска выбирается на основе некоторых статистических свойств, на этом листе строится новый дочерний элемент node, а статистика, соответствующая новому листу, и все его предки обновляются.
Учитывая все то, что жонглирование, я не настолько острый, чтобы понять, как сделать все дерево поиска хорошей неизменной структурой данных à 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, это заблуждающимся?
Кто-то спросил аналогичный вопрос здесь пару лет назад, но я думаю, что мой вопрос немного другой... У меня нет проблем с использованием monads для инкапсуляции изменчивого состояния когда это уместно, но это то, что получает "когда это необходимо", оговорка. Я беспокоюсь, что преждевременно возвращаюсь к объектно-ориентированному мышлению, где у меня есть куча объектов с геттерами и сеттерами. Не совсем идиоматический Haskell...
С другой стороны, если это разумный стиль кодирования для некоторого набора проблем, я думаю, мой вопрос становится следующим: существуют ли какие-либо известные способы сохранить этот вид кода читабельным и поддерживаемым? Я как бы измучен всеми явными чтениями и письмами и особенно сработал, переведя из моих структур STRef
внутри монады ST
в изоморфные, но неизменяемые структуры вне.