热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

monad_使用WriterMonad进行事件来源

monad在先前的文章(F#的WriterMonad,如何登录ApacheSpark,一种功能方法)中

monad

在先前的文章( F#的Writer Monad , 如何登录Apache Spark,一种功能方法 )中,我们讨论了使用Writer monad作为汇总事件的方法的想法。 但是,我们使用的是一个简单的文本记录器,与我们可以在应用程序中使用的任何常规记录器只有很小的区别。

从这种角度来看Writer monad时,似乎为日志记录聚合付出了额外的努力,而实现细节可能会使新手难以理解。

在本文中,我们将介绍Writer monad作为事件聚合器,可以将其以更通用的方式用于不同的用例,这表明它具有更广泛的可用性。 我们还将使用C#来表明该概念不仅与所谓的函数语言紧密相关,而且可以在我们选择的任何环境中使用。

主要思想是提出一种使用事件源概念以及Writer monad作为支持此工作的主要数据结构来聚合事件的方法。

活动采购

事件源是使用不可变结构将传入事件记录到我们的系统中的一种方法,以便我们可以跟踪影响系统状态的事件。 这些事件应在任何时间都可以重播,并且事件的连续流应收敛于可以通过按时间序列方式重播记录的事件而可以恢复或复制的系统状态。

为什么选择作家莫纳德?

Writer monad具有上述相同的特征,它可以记录使当前系统状态发生更改的一般事件。 同时,事件记录在不可变的结构中,而当前状态仅通过应用新事件而改变。

计算器日志

让我们从一个简单的例子开始,一个计算器实现。

我们的计算器可以执行一些操作,但是可以使用Writer monad跟踪其执行的操作。 这个初始示例与我们之前的文章中显示的相似。

请注意,我们的计算器是基于以下将要定义的称为Writer的结构定义的。 主要思想是每个操作仅知道如何使用其执行的操作来创建Writer

Writer monad的定义如下。

在这里,我们定义以下操作。

  • 通过构造函数Bind允许我们创建一个新的Writer
  • Map允许我们更改当前状态。
  • FlatMap会在记录状态更改方式的同时更改当前状态。
  • Unsafe检索当前状态和事件日志。

注意,更改状态的唯一方法是通过.Map.FlatMap

使用此结构,我们可以按以下方式使用计算器。

通过使用.UnSafe()我们可以获得当前状态和事件日志。

在这种情况下,我们仅将Writer monad用作字符串日志,也许正因为如此,到目前为止,这看起来并不那么有趣。 但是,这些是我们接下来的示例的基础。

总和

本示例说明如何使用Writer monad记录系统中发生的一系列整数事件,同时保持流处理器接收的值的总和。

首先定义源代码。

如我们所见,我们将使用无限/无限的随机整数

现在,让我们看看如何使用Writer monad接收和处理这些事件。

当事件是不可变的时,这是事件源的一个非常清楚的示例,通过重播它们,我们可以获得完全相同的最终状态,在这种情况下,该状态是所接收值的总和。

银行账户用例

最后一个示例将展示如何使用Writer monad处理发送到银行帐户的事件。 银行帐户支持两种基本操作,向其中添加资金并从中提取资金。

现在,假设我们有一个事件生成器,该事件生成器生成将由Writer monad作为流处理器处理的事务。

事务由类型ExtractionDeposit ,这两个是我们将要处理的事件类型。

现在我们有了交易源,我们将从初始化初始状态开始。

然后,我们要处理许多事件,在这种情况下,我们对其中的100个事件感兴趣,但是实际上,它可以是任意数目。

请注意,每笔交易我们在银行帐户通过执行相应的操作.FlatMapaccountState

最后,我们能够检索帐户的当前(最终)状态和已处理的事件。

有趣的是,当我们从相同的初始状态开始,然后在Writer monad日志上将相同的事务应用于初始状态时,我们应该以相同的最终状态结束。 值的状态更改是日志上记录的操作的直接结果。

使用纯功能方法

对于那些希望使用纯功能方法并避免变量accountState发生突变的用户,我们可以向IEnumerable添加.FoldLeft方法。 让我们看看如何。

首先,我们添加一个扩展方法,以便可以在C#中执行.FoldLeft

然后,我们只需要更改处理事件的方式即可。

请注意,通过这种方式,我们消除了Writer monad上的突变,而是使用.FoldLeft.FlatMap构建新的.FlatMap

结论

Writer monad提供了一种使用不可变日志来跟踪更改的功能方法,该日志可以在任何编程语言(包括C#)中使用

同样,使用.FlatMap允许我们以流畅的方式链接操作,从而提供声明性的流控制,从而促进不变性。

有时,Writer monad会被误解,并且仅与应用程序日志有关,后者是由副作用库控制的空间。 但是,Writer monad不仅仅是记录器,它还是一个事件源,可用于以一种简洁优雅的方式记录状态变化。

我们还展示了C#如何支持这种方法,证明了Monads不仅仅限于函数式语言。

翻译自: https://hackernoon.com/event-sourcing-using-writer-monad-b26a390285a

monad



推荐阅读
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
author-avatar
mbe5757086
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有