Вы, похоже, хотите получить memdb
через IO
как способ избежать передачи большего количества параметров, верно? Затем вы спрашиваете, можете ли вы (A) определить memdb
, подразумевая, что это будет функция верхнего уровня, без дополнительных затрат на загрузку данных из БД, или (B), если вы можете сохранить загруженную структуру данных с глобальной областью действия.
Оба они выполнимы с IORef
и unsafePerformIO
для определения изменяемой глобальной переменной верхнего уровня. Я не предлагаю вам сделать это. Это неуклюжий и раздражающий рефакторинг. Тем не менее, я покажу вам, как все равно:
Предположим, у вас есть функция:
make_memdb :: IO (Map K V)
Вы можете объявить изменяемую переменную верхнего уровня:
import Data.Map as M
import Data.IORef
mRef :: IORef (Map K V)
mRef = unsafePerformIO $ newIORef M.empty
{-# NOINLINE mRef #-}
main = do
m <- make_memdb
writeIORef mRef m
... do stuff using mRef ...
stuffUsingMRef ... = do
memdb <- readIORef
let vs = map (memdb !) values
return vs
Обратите внимание, что ваши функции всегда будут жить в IO
. Это потому, что вам нужно IO
, чтобы прочитать глобальную переменную, в которую вы поместили memdb
. Если вам не нравится это, и вам не нравится передавать параметры, тогда изучите монаду состояния! Я уверен, что другой ответ обсудит это, и это правильное решение.