История изменений
Исправление zinfandel, (текущая версия) :
многократного перечитывания конфига
Зачем, же. Читай конфиг один раз в начале, а потом передавай прочитанные значения в фунции.
Самым наивным подходом будет передавать каждое значение конфига как отдельный аргумент. Это быстро надоест и ты создашь ADT в котором будут сохранены все значения:
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
И будешь явно передавать этот конфиг всем функциям.
Это тоже не лучший подход, потому что нужно явно передавать. Поэтому придумали монаду Reader, в которую можно засунуть этот конфиг и читать его из каждой функции. Но потом тебе нужно будет скомбинировать монаду Reader и монаду IO, для этого понадобяться монадные трансформеры. Почитай, http://habrahabr.ru/post/184722/ и Real World Haskell про монады и монадные трансформеры. Монадные трансформеры позволяют построить стек из монад, на котором обычно держится архитектура приложения. В твоем случае это будет выглядеть примерно вот так:
main :: IO ()
main = do
conf <- readConfig
runReaderT (ldapExecuteQuery m qwr) conf -- происходит вызов ldapExecuteQuery с неявной передачей конфига
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
readConfig :: IO Config
readConfig = do
connHost <- Con.load "connHost"
let redisCon ConnectInfo {connectHost = connHost}
ldapURI <- Con.load "ldapURI"
ldapUser <- Con.load "ldapUser"
return Config redisCon ldapURI ldapUser
type App = ReaderT Config IO
ldapExecuteQuery :: ByteString -> String -> App AnswerEmailCheck
ldapExecuteQuery m qwr = do
conf{..} <- ask -- достаем конфиг
conn <- ldapInitialize ldapURI -- конфиг передается неявно
ldapSimpleBind conn -- конфиг передается неявно
result <- ldapSearch conn ldapBDN LdapScopeSubtree (Just qwr) ldapAttrs False -- то же самое
return $ getRes m result
ldapInitialize :: App Connection
ldapInitialize = undefined
ldapSimpleBind :: App Connection
ldapSimpleBind = undefined
ldapSearch :: App Connection
ldapSearch = undefined
Исправление zinfandel, :
многократного перечитывания конфига
Зачем, же. Читай конфиг один раз в начале, а потом передавай прочитанные значения в фунции.
Самым наивным подходом будет передавать каждое значение конфига как отдельный аргумент. Это быстро надоест и ты создашь ADT в котором будут сохранены все значения:
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
И будешь явно передавать этот конфиг всем функциям.
Это тоже не лучший подход, потому что нужно явно передавать. Поэтому придумали монаду Reader, в которую можно засунуть этот конфиг и читать его из каждой функции. Но потом тебе нужно будет скомбинировать монаду Reader и монаду IO, для этого понадобяться монадные трансформеры. Почитай, http://habrahabr.ru/post/184722/ и Real World Haskell про монады и монадные трансформеры. Монадные трансформеры позволяют построить стек из монад, на котором обычно держится архитектура приложения. В твоем случае это будет выглядеть примерно вот так:
main :: IO ()
main = do
conf <- readConfig
runReaderT (ldapExecuteQuery m qwr) conf -- происходит вызов ldapExecuteQuery с неявной передачей конфига
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
readConfig :: IO Config
readConfig = do
connHost <- Con.load "connHost"
let redisCon ConnectInfo {connectHost = connHost}
ldapURI <- Con.load "ldapURI"
ldapUser <- Con.load "ldapUser"
return Config redisCon ldapURI ldapUser
type App = ReaderT Config IO
ldapExecuteQuery :: ByteString -> String -> App AnswerEmailCheck
ldapExecuteQuery m qwr = do
conf{..} <- ask -- достаем конфиг
conn <- ldapInitialize ldapURI -- конфиг передается неявно
ldapSimpleBind conn -- конфиг передается неявно
result <- ldapSearch conn ldapBDN LdapScopeSubtree (Just qwr) ldapAttrs False -- то же самое
return $ getRes m result
ldapInitialize :: App Connection
ldapInitialize = undefined
ldapSimpleBind :: App Connection
ldapSimpleBind = undefined
ldapSearch :: App Connection
ldapSearch = undefined
Исходная версия zinfandel, :
многократного перечитывания конфига
Зачем, же. Читай конфиг один раз в начале, а потом передавай прочитанные значения в фунции.
Самым наивным подходом будет передавать каждое значение конфига как отдельный аргумент. Это быстро надоест и ты создашь ADT в котором будут сохранены все значения:
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
И будешь явно передавать этот конфиг всем функциям.
Это тоже не лучший подход, потому что нужно явно передавать. Поэтому придумали монаду Reader, в которую можно засунуть этот конфиг и читать его из каждой функции. Но потом тебе нужно будет скомбинировать монаду Reader и монаду IO, для этого понадобяться монадные трансформеры. Почитай, http://habrahabr.ru/post/184722/ и Real World Haskell про монады и монадные трансформеры. Монадные трансформеры позволяют построить стек из монад, на котором обычно держится архитектура приложения. В твоем случае это будет выглядеть примерно вот так:
main :: IO ()
main = do
conf <- readConfig
runReaderT (ldapExecuteQuery m qwr) conf -- происходит вызов ldapExecuteQuery с неявной передачей конфига
data Config = Config { redisConnection :: ConnectInfo
, ldapURI :: String
, ldapUser :: String
...
}
readConfig :: IO Config
readConfig = do
connHost <- Con.load "connHost"
let redisCon ConnectInfo {connectHost = connHost}
ldapURI <- Con.load "ldapURI"
ldapUser <- Con.load "ldapUser"
return Config redisCon ldapURI ldapUser
type App = ReaderT Config IO
ldapExecuteQuery :: ByteString -> String -> App AnswerEmailCheck
ldapExecuteQuery m qwr = do
conf{..} <- ask -- достаем конфиг
conn <- ldapInitialize ldapURI -- конфиг передается неявно
ldapSimpleBind conn -- конфиг передается неявно
result <- ldapSearch conn ldapBDN LdapScopeSubtree (Just qwr) ldapAttrs False -- то же самое
return $ getRes m result
ldapInitialize :: App Connection
ldapInitialize = undefined
ldapSimpleBind :: App Connection
ldapSimpleBind = undefined
ldapSearch :: App Connection
ldapSearch = undefined