Haskell-如何将具有不同依赖子集的组件连接在一起?
如何从需要各种基础设施功能子集的组件集成应用程序 有些非常简单,只需要一个配置读取器(我只想为每个业务功能公开一个相关的子集)和一个记录器。有些还需要连接到外部服务(使用缓存),我还想在其中公开与外部世界的有限范围的可能交互 我不想把多个参数显式地传递给这样的函数,也不想把它们包装在一些能够做任何事情的Haskell-如何将具有不同依赖子集的组件连接在一起?,haskell,dependency-injection,Haskell,Dependency Injection,如何从需要各种基础设施功能子集的组件集成应用程序 有些非常简单,只需要一个配置读取器(我只想为每个业务功能公开一个相关的子集)和一个记录器。有些还需要连接到外部服务(使用缓存),我还想在其中公开与外部世界的有限范围的可能交互 我不想把多个参数显式地传递给这样的函数,也不想把它们包装在一些能够做任何事情的MonadIO中 在Java应用程序容器中注入多个依赖项最接近的方法是什么?该库有类型类来表示从环境中读取配置的计算,monawarder,并将数据写入类似于记录器的东西,MonadWriter。
MonadIO中
在Java应用程序容器中注入多个依赖项最接近的方法是什么?该库有类型类来表示从环境中读取配置的计算,monawarder
,并将数据写入类似于记录器的东西,MonadWriter
。我们将使用这些作为示例
我们将使用的monawarder
部分是
class Monad m => MonadReader r m | m -> r where
ask :: m r
我们将使用的MonadWriter
部分是
class (Monoid w, Monad m) => MonadWriter w m | m -> w where Source
tell :: w -> m ()
要要求“多个依赖项”,我们需要一个为多个类型类提供实例的m
样板
最后,我们将使用中的ReaderT
和WriterT
和Identity
来运行我们的示例
{-# LANGUAGE FlexibleContexts #-}
--mtl
import Control.Monad.Reader.Class
import Control.Monad.Writer.Class
--transformers
import Control.Monad.Trans.Reader hiding (ask)
import Control.Monad.Trans.Writer.Strict hiding (tell)
import Data.Functor.Identity
使用多个依赖项:读取配置和日志
我们的读者将从以下环境中阅读:;它将提供一个monawarder配置
data Configuration = Config { site :: String }
deriving Show
我们的记录器将累积一个消息列表,每个消息都是一个字符串。它将提供一个MonadWriter[String]
您可以通过要求多个类型类的实例来要求多个功能。要做到这一点,您可以需要一个m
,它同时具有MonadWriter
和MonadWriter
的实例。这是一个组件,它需要一个从中读取配置的环境和一种写入日志消息的方法
logConfig :: (MonadWriter String m, MonadReader Configuration m) => m ()
logConfig = do
config <- ask
tell [show config]
举例
我们将在另一个更大的示例中使用前面的logConfig
:
example :: (MonadWriter [String] m, MonadReader Configuration m) => m ()
example = do
tell ["Starting", "Logging Config"]
logConfig
tell ["Done Logging Config", "Done"]
最后,我们将使用配置运行示例
,并查看它的功能。请注意,此处的IO
仅用于输出用于运行示例的最终结果
main :: IO ()
main = print . runDepsIdentity example $ Config {site = "StackOverflow"}
这将产生以下输出
((),["Starting","Logging Config","Config {site = \"StackOverflow\"}","Done Logging Config","Done"])
((),["Starting","Logging Config","Config {site = \"StackOverflow\"}","Done Logging Config","Done"])