- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
用于依赖注入(inject)的惯用 Haskell 解决方案是什么?
例如,假设您有一个接口(interface) frobby
,并且您需要传递符合 frobby
的实例周围(这些实例可能有多种,例如 foo
和 bar
)。
典型操作是:
具有某些值的函数 X
并返回一些值Y
。例如,这可能是一个数据库访问器,接受 SQL 查询和连接器并返回数据集。您可能需要实现 postgres、mysql 和模拟测试系统。
具有某些值的函数Z
并返回与 Z
相关的闭包,专门针对给定的foo
或bar
样式,在运行时选择。
一个人解决了这个问题,如下:
http://mikehadlow.blogspot.com/2011/05/dependency-injection-haskell-style.html
但我不知道这是否是管理此任务的规范方法。
最佳答案
我认为正确的答案是,我可能会因为这样说而收到一些反对票:忘记术语依赖注入(inject)。把它忘了吧。这是面向对象世界的流行语,但仅此而已。
让我们解决真正的问题。请记住,您正在解决一个问题,而该问题就是手头的特定编程任务。不要让你的问题成为“实现依赖注入(inject)”。
我们将以记录器为例,因为这是许多程序都希望拥有的基本功能,并且有许多不同类型的记录器:一种记录到 stderr,一种记录到文件,一个数据库,一个什么也不做的数据库。要统一所有它们,您需要一个类型:
type Logger m = String -> m ()
您还可以选择更高级的类型来节省一些击键:
class PrettyPrint a where
pretty :: a -> String
type Logger m = forall a. (PrettyPrint a) => a -> m ()
现在让我们使用后一种变体定义一些记录器:
noLogger :: (Monad m) => Logger m
noLogger _ = return ()
stderrLogger :: (MonadIO m) => Logger m
stderrLogger x = liftIO . hPutStrLn stderr $ pretty x
fileLogger :: (MonadIO m) => FilePath -> Logger m
fileLogger logF x =
liftIO . withFile logF AppendMode $ \h ->
hPutStrLn h (pretty x)
acidLogger :: (MonadIO m) => AcidState MyDB -> Logger m
acidLogger db x = update' db . AddLogLine $ pretty x
您可以看到这是如何构建依赖关系图的。 acidLogger
依赖于 MyDB
数据库布局的数据库连接。将参数传递给函数是表达程序中依赖关系的最自然的方式。毕竟,函数只是一个依赖于另一个值的值。对于行动来说也是如此。如果您的操作取决于记录器,那么它自然是记录器的函数:
printFile :: (MonadIO m) => Logger m -> FilePath -> m ()
printFile log fp = do
log ("Printing file: " ++ fp)
liftIO (readFile fp >>= putStr)
log "Done printing."
看看这有多容易吗?在某些时候,这会让你意识到,当你忘记了面向对象教给你的所有废话时,你的生活会变得多么轻松。
关于haskell - Haskell 中的依赖注入(inject) : solving the task idiomatically,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14327327/
我正在使用 spyder - python。我想测试我的代码。我已关注 pip install spyder-unittest和 pip install pytest .我已经重新启动了内核并重新启动
我编写了一个简单的代码来匹配和选择/丢弃两个文件中的元素。此代码适用于包含 Id 对的 $file_in: Id1 Id2 Id1 Id3 Id1 Id4 Id3 Id4 Id3 Id5 Id3 Id
问题陈述:当 for 循环第二次执行时,我收到 Stale Element Exception。 描述: 我正在使用 for 循环来处理表元素。在第一次迭代中,它将在页面上搜索所需的元素。如果该元素在
我编写了一个简单的代码来匹配和选择/丢弃两个文件中的元素。此代码适用于包含 Id 对的 $file_in: Id1 Id2 Id1 Id3 Id1 Id4 Id3 Id4 Id3 Id5 Id3 Id
我正在尝试用 Java 创建康威的生命游戏,但似乎遇到了障碍。我创建了一个名为“Cell”的类,它包含一个 boolean 变量,该变量本质上确定细胞是活的还是死的,以及在需要时杀死或创建细胞的方法。
我有一张 table userid points expires我只想对所有匹配特定 userid 的点求和和 CURTIME() < expires . 所以我做到了: select *, su
题目地址:https://leetcode.com/problems/solve-the-equation/description/ 题目描述: Solve a given equation an
自从工作流构建问世以来,我一直在使用 TFS 构建。我从未见过使用以下任何一项的需要或愿望: Copy Build output to the server 什么服务器?什么目录? `将构建输出复制到
我有这个矩阵 a = {{2, -2, -4}, {-2, 5, -2}, {-4, -2, 2}} 然后我解出了一个缺少一项的方程。方程的形式为逆[p].a.p == q其中 p 是缺少条目 (x5
下面的代码解决了 hanoi 使用预定义函数 moveLOD、swapLOI 和 swapLID 返回 Action 列表的问题。 MoveLOD:将 1 个圆盘从第一个位置移动到三元组第三个位置中的
基本上,我通过从文本文件中读取一组整数来实现 AVL 树,然后使用 add() 方法填充树。另外,程序应该按顺序打印整数集。 当我运行该程序时,会弹出 StackOverflowError。我认为这个
我在 html 中有一个 span 标签,这个 可以在页面上多次出现。 我只想选择第一个跨度标签。我就是这样做的 var $myvar= $(".mydiv .indiv .myspan:first"
来自 sympy solve() 的解决方案是否以某种方式排序?它是从最小到最大的解决方案吗? 如何强制解决方案的非负性? 在我的问题中,我需要独特的最小正解决方案。我感谢所有的帮助 最佳答案 它们不
我正在尝试打开一个文件,但我收到了: 该进程无法访问该文件,因为它正被另一个进程使用。该文件是一个 XML 文档。谁能帮忙? string activeDirectory = @"X:\SubGr
如何解决此内存泄漏...我什至在最后释放它,如图片所示,但它仍然存在。在 if 语句几乎 10-15 条件下,它像给定的代码一样使用......但最后我发布了它。 LoginResponse *res
我为不同的日子编写了以下代餐代码,但我每天都吃同样的餐。我想隔天吃“肉”和“素食”食物。 my dataframe is as follows: id name
这会创建一个点列表,sympy solve() 方法应该返回 x 的值。相反,它返回另一个方程式,我不确定为什么。 ogrid() 和 ravel() 正在绘图中创建一个点列表,这是在 Matplot
只是好奇它是否使用高斯消去法或其他等效方法? 最佳答案 来自numpy docs : solve is a wrapper for the LAPACK routines dgesv and zges
首先, solve_poly_system( seq, *gens, **args), 有人确切知道solve_poly_system的参数是什么意思吗? 我有系统, rd = λk ua = λk
我正在尝试使用 sympy 的 solve 命令求解方程,但我的输出是一个空列表 [ ]。我认为这可能发生的唯一原因是没有解决方案,但我怀疑这就是原因。任何人都知道为什么我没有得到答案?谢谢! fro
我是一名优秀的程序员,十分优秀!