Модульная разработка программ - объединение монадных трансформаторов в функции монадной агностики

Я пытаюсь придумать дизайн модульной программы и еще раз прошу вашей помощи.

Как продолжение этих следующих постовМонадные Трансформаторы против Проходящих Параметров а такжеКрупномасштабный дизайн в ХаскелеЯ пытаюсь построить два независимых модуля, которые используют Monad Transformers, но предоставляют функции, независимые от Monad, а затем объединяют функцию Monad-независимую от каждого из этих модулей в новую функцию, независимую от Monad.

Мне не удалось запустить функцию объединения, например, как мне позвонитьmainProgram с помощьюrunReaderT в приведенном ниже примере?

Дополнительный вопрос: есть ли лучший способ достичь той же цели модульного дизайна?

В примере есть два фиктивных модуля (но компилируются), один из которых выполняет ведение журнала, а другой - читает пользовательский ввод и манипулирует им. Функция объединения считывает вводимые пользователем данные, регистрирует их и распечатывает.

{-# LANGUAGE FlexibleContexts #-}

module Stackoverflow2 where

import Control.Monad.Reader

----
---- From Log Module - Writes the passed message in the log
---- 

data LogConfig = LC { logFile :: FilePath }

doLog :: (MonadIO m, MonadReader LogConfig m) => String -> m ()
doLog _ = undefined


----
---- From UserProcessing Module - Reads the user Input and changes it to the configured case
----

data  MessageCase = LowerCase | UpperCase deriving (Show, Read)

getUserInput :: (MonadReader MessageCase m, MonadIO m) => m String
getUserInput = undefined

----
---- Main program that combines the two
----                  

mainProgram :: (MonadReader MessageCase m, MonadReader LogConfig m, MonadIO m) => m ()
mainProgram = do input <- getUserInput
                 doLog input
                 liftIO $ putStrLn $ "Entry logged: " ++ input

Ответы на вопрос(2)

Ваш ответ на вопрос