首页
学习
活动
专区
圈层
工具
发布

让Monad来得更猛烈些吧_Haskell笔记11

如果把附加的日志信息看做context,似乎与Monad有些关系,比如可以在值参与运算的同时,自动收集日志(维护这个context) 这就是Writer的由来: Writer则是加进一个附加值的context...P.S.能够从共享环境中读取值,这也是称之为Reader Monad的原因 三.State Monad 除日志追踪、共享环境外,还有一类最常见的问题是状态维护 然而,有一些领域的问题根本上就是依赖于随着时间而改变的状态...虽然我们也可以用 Haskell 写出这样的程序,但有时候写起来蛮痛苦的。这也是为什么 Haskell 要加进 State Monad 这个特性。...这让我们在 Haskell 中可以容易地处理状态性的问题,并让其他部份的程序还是保持纯粹性。...五.Monad的魅力 Monad能够赋予计算一些额外的能力,比如: Writer Monad:能够把函数转换成带日志的版本,用来追踪执行过程,或者给数据变换添加额外的信息 Reader Monad:能够让一系列函数在一个可控的共享环境中协同工作

1.9K40
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Scalaz(18)- Monad: ReaderWriterState-可以是一种简单的编程语言

    说道FP,我们马上会联想到Monad。我们说过Monad的代表函数flatMap可以把两个运算F[A],F[B]连续起来,这样就可以从程序的意义上形成一种串型的流程(workflow)。...看看StateT,简单定义应该是这样的:  case class StateT[F[_],S,A](run: S => F[(S,A)]) 我们可以把F类堆砌在State上。...好了,scalaz里有个ReaderWriterState这么个type class,就是一个Reader+Writer+State堆砌的Monad。...在scalaz里是这样定义的:scalaz/ReaderWriterStateT.scala /** A monad transformer stack yielding `(R, S1) => F[(...先传入一个端口号,在程序中可以重设使用的端口号: 1 val program: ReaderWriterState[Config, List[String], Int, Int] = for { 2

    1.7K70

    深入理解函数式编程(下)

    React Hooks的设计是很巧妙的,以useEffect为例: 在函数组件中,useState用来产生状态,在使用useEffect的时候,我们需要挂载这个state到第二个参数,而第一个参数给到的运行函数在...实际在函数式编程语言实现中,Maybe确实只是一个类型(称为代数类型),具体的一个值有具体类型Just或Nothing,就像数字可以分为有理数和无理数一样。...除了这种值存在与否的判断,我们的程序还有一些分支结构的方式,因此我们来看一下在Monad空间中,分支情况怎么去模拟?...其他的编程语言特性,在函数式编程中也能找到对应的影子,比如循环结构,我们往往使用函数递归来实现。 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。...Q:你愿意在生产中使用Haskell/Lisp/Clojure等纯函数式语言吗? A:不论是否愿意使用,现在很多语言都开始引入函数式编程语法了。并不是说函数式编程一定是优秀的,但它至少没有那么恐怖。

    82210

    不可变的状态

    如果我们在程序中定义的函数和数学函数一样,不依赖可变状态,也不产生副作用,那么我们就可以很好地解决之前提到的问题。这也是为什么一些语言在语法上就鼓励不可变。...在之前的实现中,我们显式地在 labelTree 的调用中传递了状态,并将这个过程泛化到可以处理任意标签的情况,我们此时可以发现,状态和状态的转变其实是一个非常一般的情况,对于这样的情况,我们可以构建一个新的类型专门用来表示它...这样我们就可以知道为什么 Monad 这个概念要被拿来在编程上使用,虽然它的定义本身有点不知所云,但它确实能构建一个强大的抽象,使得程序变得明晰。...只不过 IO 所管理的状态不是一个变量而是程序与整个世界之间交互的所有 IO 操作。在 Haskell 中,IO Monad 是一个基础的 Monad 6。...而在这样的环境下,Haskell 产生输入输出这样的副作用的方式就是使用 IO Monad。

    1.3K20

    Scalaz(43)- 总结 :FP就是实用的编程模式

    那么Monad真的像许多人感觉的那样神秘、虚渺、触不可及吗?答案是否定的。...接触的多了我们就可以了解Monad的主要作用就是把一个算法,无论是一个值或者一个函数升格成Monad,这样我们就可以在Monad-for-comprehension里使用它们了。...看看scalaz里一些类型的Monad格式吧: case class State (run: S => (A,S)) case class Reader(run: A => B) case class...好了,有了Monad和各种功能转换、集合方式,我们可以在for-comprehension里进行熟悉的编程了。那么会不会出现在一个for-loop里出现几百行指令的情况呢?...它可以把影响函数组合的副作用放到算法(interpret)阶段,让我们能够在算式中实现程序间的组合。

    1.3K70

    当我们谈论Monad的时候(二)

    不过由于列表可以是任意长的,因此需要定义一个链状的结构 data List a = Nil | Cons a (List a) infixr 5 `Cons` 在Haskell中,用`包裹的函数可以作为中缀函数使用...Do-notation Do表记(do-notation)是Haskell给Monad操作提供的语法糖。在不使用Do表记情况下,使用Monad的代码是相当混乱的。...在IO操作中,这个优势还可以变得更加的明显。Haskell采用Monad实现IO相关的API,这个Monad就称为IO Monad。...Haskell中的IO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前的结果。对于部分IO Monad(如putStrLn返回的),我们直接就抛弃了这些返回值。...这里用到了一个技巧,Haskell的Applicative实际上是很灵活的,它允许我们在声明时选择或liftA2进行声明。liftA2的作用就是上一篇中提到的liftM2。

    1.4K10

    Scalaz(17)- Monad:泛函状态类型-State Monad

    那么我们就应该像函数式运算T值一样,也有一套函数式更新程序状态的方法。之前我们介绍了Writer Monad。Writer也是在F[]内维护Log的,可以说是一种状态维护方式。...由于Writer是个Monad,通过flatMap可以把状态值W在运算之间连续下去。...曾经提到过Writer还可以被理解成一种特别的状态维护,只是目标锁定在了Log的更新。那么真正意义的状态类型State Monad又是怎样的呢?...所以这些状态维护函数必须在MonadState子类实例存在的情况下才能使用。这个情况在object MonadState里的apply函数的隐式参数F可以推断得出。...还是介绍些实际点的例子吧。最好能把在现实应用中如何选择使用State的思路过程示范一下。

    2.1K80

    当我们谈论Monad的时候(一)

    先前我在某群提到,从Optional(也就是Haskell的Maybe)理解Monad会是一个很不错的方式。...之后,用Haskell作为过渡,最后在讲讲理论相关的内容。而第一篇作为工程部分,自然用的是大家最喜欢的Java主要是我最喜欢来讲解了。...不过我先打个预防针,本篇文章是站在工程角度的浅显介绍,因此语言可能不甚严谨。 Monad是层数很高的抽象 和Runnable一样,Monad是一个功能的抽象。在Java中,我们可以用接口类来描述它。...更有意思的一件事情是,使用flatMap也可以实现join函数。也就是说,我们也能定义出Monad!...下一篇文章,我将简单介绍Haskell中的Monad实现与一些有趣的Monad,作为过渡。再下一篇,我将从理论角度(主要是范畴论)介绍Monad。

    74010

    Scalaz(41)- Free :IO Monad-Free特定版本的FP语法

    上面的Tower[IvoryTower]是状态切换函数的输入类型,不参与实际运算(不在任何运算中调用如: rw -> a),起一种状态标签作用(state tag)。...所以我们说IO Monad就是在FP模式中进行行令编程的通用方式。可以想象我们可能会在IO这个壳子内进行我们熟悉的程序编写。那么IO Monad到底能不能符合在FP环境内的行令编程要求呢?...我们需要在IO[A]这种Monad之上增加Option的作用,可以用Monad Transformer来实现: 1 implicit def ioToOptionT[A](io: IO[A]):...同样如果我们希望把用户的输入记录下来,我们可以用Writer的功能来实现。...当然,我们可以同时拥有Option和Writer的作用,这时的Monad Transformer就是三层的了,我们在前面的这篇讨论也做过示范。

    1.8K90

    Haskell爬虫中日志记录:监控HTTP请求与响应

    调试问题:快速定位运行中的错误和异常。遵守政策:记录遵守robots.txt协议的情况,确保爬虫行为合规。分析效率:评估爬虫的性能和资源消耗。...相关日志记录过程如下:集成monad-logger首先,需要在项目的.cabal文件中添加monad-logger和log包的依赖:日志记录器使用monad-logger,可以定义一个日志记录器,它将被用于记录...这可以通过包装HTTP请求函数来实现:记录HTTP响应状态对于每个响应,记录其状态码和可能的错误信息:实现日志后端日志可以输出到控制台、文件或通过网络发送到日志服务器。...,我们了解到在Haskell编写的爬虫中实现日志记录的重要性和方法。...日志记录不仅可以帮助开发者监控爬虫的行为,还可以在出现问题时提供调试信息。使用monad-logger和log包,我们可以轻松地在Haskell中实现灵活且强大的日志记录

    84110

    Monad_Haskell笔记10

    P.S.关于computation context的详细信息,见Functor与Applicative_Haskell笔记7 用来解决context相关计算中的另一个场景:怎样把一个具有context的函数应用到具有...函数输入context里的值,输出普通值 + context里的值:直接调用 函数输入context里的值,输出普通值 + 普通值:用pure包一下再调 所以,就这个场景(把是否处于context里的函数应用到是否处于...Just (show x ++ y) 类比不涉及context的普通计算: let x = 3; y = "!"...在do表示法中的作用 把Monad laws换成do表示法描述的话,就能得到另一组等价转换规则: -- Left identity do { x′ <- return x; f x′ } ≡...,应对一些通用场景,比如错误处理,I/O,不确定结果数量的计算等等,其存在意义是:比Applicative更灵活,允许在每一步计算中添加控制,像Linux管道一样 参考资料 Monad The forall

    1.2K50

    什么是 Monad (Functional Programming)?函子到底是什么?ApplicativeMonad

    也就是说,如果我们要将普通函数应用到一个有盒子上下文包裹的值,那么我们首先需要定义一个叫Functor的数据类型,在这个数据类型中需要定义如何使用map或fmap来应用这个普通函数。...image.png fmap的输入参数是a->b函数,在我们这个案例中是(+3),然后定义一个函子Functor,这里是Haskell的Just 2,最后返回一个新的函子,在我们案例中,使用Haskell...澄清了函子的含义,那么如何在程序中表达它? 在Haskell中,函子是在其上可以map over的东西。稍微有一点函数式编程经验,一定会想到数组(Array)或者列表(List),确实如此。...在Haskell这类的强类型语言中,我们甚至可以组装自己的Tuple Monad。...(组合箭头和元箭头映射这里省略) 函子这种映射实际是一种分解组合方式,对于这个过程我们可以用下面模拟形象地理解: 计算C集合中每个函数的"结果", 但是不组合它们.

    5.2K30

    铁定不纯的IO_Haskell笔记5

    放到do语句块里 在GHCi环境输入I/O Action再回车,如putStrLn "hoho" 执行 可以把main当做普通函数在GHCi环境下执行,例如: > :l echo [1 of 1] Compiling...把处理结果写入文件,符合预期 四.System.IO 之前使用的getLine、putStrLn都是System.IO模块里的函数,常用的还有: -- 输出 print :: Show a => a -...惰性I/O 字符串本身是一个惰性List,getContents也是惰性I/O,不会一次性读入内容放到内存中 toUpperCase'的示例中会一行一行读入再输出大写版本,因为只在输出的时候才真正需要这些输入数据...hGetContents或hGetLine要文件内容了,最后通过hClose释放文件指针相关的资源。...Handle) -- 定义在System.Directory模块中,用来删除指定文件 removeFile :: FilePath -> IO () -- 定义在System.Directory模块中

    1.9K30

    【单子】说白了不过就是【自函子范畴】上的一个【幺半群】而已?请说人话!!

    怕生词概念的同学先别慌,先告诉你 Monad 和 Promise 很像,增点亲切感; 浅尝 Monad 在函数式编程中我们一直强调:纯函数、纯函数、纯函数!无副作用,无副作用,无副作用!...直接上代码,看看 Monad 在实际应用中是怎么写的: var fs = require("fs"); // 纯函数,传入 filename,返回 Monad 对象 var readFile = function...,是否还能做到:有效解释?...可以直接这样理解:Monad 是一种特殊的数据结构,它能把值进行包装,然后链接执行;王垠在《对函数式语言的误解》中准确了描述了 Monad 本质: Monad 本质是使用类型系统的“重载”(overloading...推荐阅读 函数式语言的宗教 图解 Monad JS 中 Monad 学习函数式编程 Monad monadic.ts 如何解释 Haskell 中的单子(Monad)

    1.5K20

    ✨从代码复用讲起,专栏阶段性作结,聊聊?

    可惜就是没有生产出一个好的轮子,可以直接供业务开发中使用。这感觉就像:我知道这东西很牛b,但是就还不能发挥出它十足的威力。 fine,理论指导实践,实践是检验真理的标准。...这让人不禁联想到 JS 中同样让人头疼的东西,this 的绑定策略: 情况 1. 默认绑定 情况 2. 隐式绑定 情况 3. 显示绑定 情况 4. new 绑定 具体就不展开了,也同样让人会“谢”。...Vue3 Setup 后来大佬又带来了 Vue3 Composition API ,“好呀好呀" 用类似于react hook 式的函数式组件: 隐式输入、输出,变成了显示输入、输出,这不就是函数式编程思想中无副作用的纯函数一直要求的吗...Number) 改造成 (Number -> (Number,String)) 以上就是最简单的 monad,在 Haskell 标准库中,它被称为 Writermonad 说白了,就是把函数和值都改造成一个可组合的形式...正确是借助 Monad 思想: 用 bind 函数将 children 函数改造成可组合的形式,即输出的类型和输入的类型一致,这样就可以组合了。

    84210

    来看看几种 Monad来看看几种 Monad

    他是被 Haskell 用在处理语法错误的情况。我们目前不需要太在意 fail。 我们知道了 Monad typeclass 长什么样子,我们来看一下 Maybe 的 Monad instance。...do 表示法 Monad 在 Haskell 中是十分重要的,所以我们还特别为了操作他设置了特别的语法:do 表示法。...不过他还是让我们了解到怎么使用 do。 在 do 表示法中,我们其实可以用模式匹配来绑定 monadic value,就好像我们在 let 表达式,跟函数参数中使用模式匹配一样。...毕竟在 let 表达式的情况下并没有失败就跳下一个的设计。至于在 do 表示法中模式匹配失败的话,那就会调用 fail 函数。他定义在 Monad 的 type class 定义猪。...但他不会检查单子律是否有被遵守,所以如果我们要写一个 Monad 的 instance,那最好我们确定他有遵守单子律。我们可以不用担心标准函数库中的型态是否有遵守单子律。

    1.4K20

    Scalaz(13)- Monad:Writer - some kind of logger

    多个flatMap同时作用可以形成一个程序运行链。我们可以在flatMap函数实现中增加一些附加作用,如维护状态值(state value)、跟踪记录(log)等。   ...在上一篇讨论中我们用一个Logger的实现例子示范了如何在flatMap函数实现过程中增加附加作用;一个跟踪功能(logging),我们在F[T]运算结构中增加了一个String类型值作为跟踪记录(log...这点从flatMap函数的实现可以证实。 当然我们必须获取Logger的Monad实例才能使用for-comprehension。...当我们为任何类型A提供注入方法来构建这个Writer结构后,任意类型的运算都可以使用Writer来实现在运算过程中增加附加作用如维护状态、logging等等。...现在任何类型A都可以使用set和tell来构建Writer类型了: 1 3 set Vector("Entered Int 3") //> res2: scalaz.Writer

    1.1K100
    领券