Tag: Monad

Monad Menagerie

在上一篇文章中,我花了一些时间看一下Monads —数据结构提供了称为bind或flatMap (或>>>= )的功能。 Monads为我们提供了一种强大的新功能组合方式。 然后,我花了一些时间来尝试了解Monad是什么。 最后,我们看到Optionals , Arrays和WebData类型都是Monad(并为它们定义了bind )。 在本文中,我将介绍很多基础知识,看看一些我们在Swift中不经常看到的Monad(或至少不经常被视为Monad)的Monad示例: Readers , Writer和Futures。 所有示例都可以在Github上找到。 有一个游乐场可以尝试。 请注意,为了使本文中的代码示例简短,我漏掉了一些细节-您可以在Github中查看工作代码。 作家✍️ 让我们开始与作家。 Writer可以将一个值与有关该值的一些信息打包在一起; 随着我们在后续计算步骤中继续处理该值,我们可以继续添加信息。 它通常用作记录进度或跟踪运行总计的一种方式。 在许多地方,您会使用一个突变状态(例如,一个inout参数,对全局日志记录功能的写入,甚至只是一个print语句),但是这些操作很难测试,并且在多线程环境中无法很好地工作。 Writer有两个类型参数:第一个是“登录”或“累积”的类型; 第二个是计算的当前值。 换句话说,我们有: Writer V (计算值)可以是任何类型,但是A (累加器)必须是称为Monoid的特殊类型。 Monoids¹只是带有“加法”运算符的类型,表示为和“零”或“空”值。 我不会在本文中介绍Monoid(请查看github代码以获取更多信息),但请注意Array和Int都是Monoid。 Int的“零”当然是0 ; 而“加法”运算符当然是+ 。 更有趣的是,Array的“零”为[] ,加法为.append或+ 。 因此,举例来说,假设我们正在编写一个图形包来处理图片。 struct Picture { let pixels: [UInt8] … } 我们希望保留所有操作的记录。 为了保持跟踪而不改变状态,我们需要将记录传递到每个操作函数中,如下所示: func makeGreyScale( log: [String] ) […]

另一个Monad教程

适用于Swift程序员 介绍 函子和monad是一个概念,每个开始学习函数式编程的人迟早都会联系起来,并且通常很难与之抗争。 Monad是一个简单的概念:它具有简洁明了的定义。 另一方面,此定义基于多个抽象层,这使它很难掌握。 我们可以认为monad是简单的(与复杂相反),但是对于大多数人而言,学习monad通常很困难(与easy相反)。 要了解其完整的应用和通用性,这是最困难的事情之一。 这可能是一个解释,为什么周围会有无数的monad教程。 在建立了处理这些抽象的思维模型并获得对概念本身的良好理解之后,通常人们会尝试使过程对于新手来说更加可口,从而使编写教程几乎成为通俗的“通过仪式”。 我认为这与我没什么不同,所以我们继续。 在接下来的系列文章中,我的重点是就我在此过程中发现的陷阱进行思考。 我希望它将使本教程至少与以下术语中已有的一些教程有所不同: 我将尝试使本教程尽可能地实用,探索概念,但尝试将其付诸实践(理解为:代码)。 把它带入这个领域,对我们作为程序员来说更清楚,这对我有所帮助,我也希望可以对其他人有所帮助。 几种有关monad的解释试图使用隐喻来使其变得不太抽象。 在这些隐喻上,单子表示为设计图案,容器或盒子,卷饼,鸭带或“可编程分号”。 尽管它们都可以为单声道模型建模,但是有很多概念和抽象不适合或需要某种调整才能保持。 这就是为什么詹姆斯·伊里(James Iry)说单子像大象(使用盲人和大象的寓言)的原因:您可以有一些直觉或理解概念的某些部分,但仅看到细节会使您错过整个画面。 不知何故,我同意布伦特·约基(Brent Yorgey)的观点,即试图将这一概念适合于隐喻是一种谬论,因为它最大程度地减少了与抽象的斗争是理解过程的一部分。 因此,我将尝试着重于概念而不是隐喻,但我将尝试使用它们指出我在学习过程中与该隐喻有关的一些陷阱(我认为这些观点使我更难理解。概括这个概念)。 根据概念和示例,本教程分为多个小帖子。 我希望它使跟踪和跳过已知部分变得容易。 绝大多数monad教程都使用Haskell进行举例说明。 Haskell是一种纯函数式语言,其语法与大多数程序员习惯使用的命令式和OO语言截然不同。 因此,尝试阅读它们会带来两个挑战,而不是一个挑战:理解概念和语言本身。 找到这个Scala教程对我的学习至关重要。 Scala是一种多范式语言,尽管具有强大的构造,但比Haskell更易于阅读(至少对我而言)。 在本教程中,我将使用Swift,也是一种多范式语言,但我认为它也可以轻松转换为其他多范式语言。 我需要带些什么? 我将重点介绍monad概念及其理解的基石。 有一些以前的知识,我不会关注,但是非常重要: Swift-代码示例是使用Swift语言编写的,因此尽管我认为可以轻松地将其映射到其他编程语言(例如C#,Java,Kotlin等),但是该语言的知识非常重要。 泛型 -泛型类型是monad的基础。 理解概念及其语法很重要,以便理解本教程中的示例和代码。 函数式编程 — Monad是与函数式编程范例相关联的构造,因此了解它以了解monad的用途及其用法很重要。 本教程有两个基本概念:函数组成和函数是函数编程中的“一等公民”(它们是类型,它们就像任何其他类型一样,可以将它们归为变量,并将其作为参数传递到另一个函数或作为函数调用的结果返回)。 所有这些都说明了这一点,并希望我至少可以部分摆脱“ monad诅咒”(当某人终于能够理解它时,他无法向任何其他人解释它),让我们从这里开始。 如果您想转至特定职位,则以下是所有与monad相关的帖子的列表。