Welcome to Haskell 在上一篇文章中,我通过几个Java的例子简单的说明了Monad的本质和一些工程中常见的用途。接下来的文章就不再侧重于工程了,而是要慢慢向理论转换。...的instance,因为在Haskell中,Functor与Monad之间还有一个Applicative。...Haskell中全符号的、被小括号包裹的函数默认是中缀的,比如这个函数的调用就是中缀形式f xs。接受一个容器内的函数和值,并将运算之后的结果重新放在容器中。...在IO操作中,这个优势还可以变得更加的明显。Haskell采用Monad实现IO相关的API,这个Monad就称为IO Monad。...而且在范畴论中,Monad也是这么定义的。
先前我在某群提到,从Optional(也就是Haskell的Maybe)理解Monad会是一个很不错的方式。...之后,用Haskell作为过渡,最后在讲讲理论相关的内容。而第一篇作为工程部分,自然用的是大家最喜欢的Java主要是我最喜欢来讲解了。...Monad是层数很高的抽象 和Runnable一样,Monad是一个功能的抽象。在Java中,我们可以用接口类来描述它。就像你说Thread是Runnable一样,我们也同样可以说XX类是Monad。...不光如此,有了join函数,我们还可以很简单的构造出flatMap函数。...下一篇文章,我将简单介绍Haskell中的Monad实现与一些有趣的Monad,作为过渡。再下一篇,我将从理论角度(主要是范畴论)介绍Monad。
♣ 题目部分 在Oracle中,I/O Calibration和DOP有什么关系?...当PARALLEL_DEGREE_POLICY被设置为AUTO时,Oracle数据库将会基于执行计划中操作的成本和硬件特性来判断是否使用并行。...如果一个PARALLEL Hint在语句级被使用,那么无论PARALLEL_DEGREE_POLICY的值设置成什么,自动并行度都将被开启。...若使用了DOP,则可以在执行计划的Note部分可以看到类似于“automatic DOP: Computed Degree of Parallelism is 2”的信息。...如果是使用ASM来管理数据库文件,那么就是指存储数据的磁盘组,那么只有存储数据的磁盘组中的物理磁盘作为num_disks变量值,不包含FRA磁盘组中的物理磁盘。
有一个特殊幺元,能够和任何元素组合,导致的结果是不改变这些元素。 函子到底是什么? 一个函子Functor是任意类型,这些类型定义了如何应用 map (fmap in Haskell) 。...image.png fmap的输入参数是a->b函数,在我们这个案例中是(+3),然后定义一个函子Functor,这里是Haskell的Just 2,最后返回一个新的函子,在我们案例中,使用Haskell...image.png 图中范畴C1和范畴C2之间有映射关系,C1中Int映射到C2中的List[Int],C1中String映射到C2中的List[String]。...在Haskell中,函子是在其上可以map over的东西。稍微有一点函数式编程经验,一定会想到数组(Array)或者列表(List),确实如此。...在Haskell这类的强类型语言中,我们甚至可以组装自己的Tuple Monad。
但是 fmap 怎么知道如何应用该函数的呢? 究竟什么是 Functor 呢? 在 Haskell 中 Functor 是一个类型类。 其定义如下: ?...Applicative 定义了 (*)(在 Haskell 中是 ),它知道如何将一个 包装在上下文中的 函数应用到一个 包装在上下文中的 值上: ?...然后把它扔掉,因为在本节中你并不需要! Monad 增加了一个新的转变。 Functor 将一个函数应用到一个已包装的值上: ?...Monad 有一个函数 ))=(在 Haskell 中是 >>=,读作“绑定”)来做这个。 让我们来看个示例。 老搭档 Maybe 是一个 monad: ?...在 Kotlin 中,可以认为 Monad 是一种定义了这样中缀函数的类型: infix fun Monad.`))=`(f: ((T) -> Monad)): Monad<R
函数表达的映射关系在类型上体现在特定类型(proper type)之间的映射。 什么是自函数(Endofunction)?...范畴 图中范畴C1和范畴C2之间有映射关系,C1中Int映射到C2中的List[Int],C1中String映射到C2中的List[String]。...在Haskell中,函子是在其上可以map over的东西。稍微有一点函数式编程经验,一定会想到数组(Array)或者列表(List),确实如此。...,String) 注: 在Haskell中称为 liftM var bind = function(f) { return function F(tuple) { var x = tuple...在Haskell这类的强类型语言中,我们甚至可以组装自己的Tuple Monad。
并且对于遵守Functor laws和Monad laws的类型,这两个函数是完全等价的,例如: > liftM (+1) (Just 1) Just 2 > fmap (+1) (Just 1) Just...) 我们知道有liftA2(直到liftA3),用来应对“多参”函数: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c liftA3...可以用join函数: join :: Monad m => m (m a) -> m a 试玩一下: > join (Just (Just 1)) Just 1 > join Nothing Nothing...> join (Just (Just (Just 1))) Just (Just 1) 注意,类型上要求内层和外层的Monad相同(都是m),所以join (Just [1])之类的是无法正常工作的...中的k就是id,所以仅原样取出内层Maybe值 P.S.另外,一个有趣的东西: m >>= f = join (fmap f m) 也就是说>>=等价于用转换函数(f :: a -> m b)对monadic
Haskell,以其强大的类型系统和函数式编程特性,成为了编写高效、可靠爬虫的理想选择。然而,随着爬虫的运行,监控其行为变得尤为重要。...Haskell日志记录工具Haskell社区提供了多种日志记录解决方案,其中log包是一个流行的选择。它基于monad-logger库,支持多种日志级别和灵活的日志处理。...相关日志记录过程如下:集成monad-logger首先,需要在项目的.cabal文件中添加monad-logger和log包的依赖:日志记录器使用monad-logger,可以定义一个日志记录器,它将被用于记录...以下是一个简单的控制台日志后端实现:集成到爬虫主函数将日志记录集成到爬虫的主函数中,确保所有HTTP交互都被记录:代码实现以下是本文中提到的Haskell爬虫日志记录的完整实现代码:{-# LANGUAGE...使用monad-logger和log包,我们可以轻松地在Haskell中实现灵活且强大的日志记录
P.S.关于computation context的详细信息,见Functor与Applicative_Haskell笔记7 用来解决context相关计算中的另一个场景:怎样把一个具有context的函数应用到具有...context的值 (>>=) :: (Monad m) => m a -> (a -> m b) -> m b 如果你有一个具有context的值m a,你能如何把他丢进一个只接受普通值a的函数中,并回传一个具有...Just 1 >>=登场: > Just 1 >>= \x -> Just (x + 1) Just 2 三者的关联 从接口行为来看,这三个东西都是围绕具有context的值和函数在搞事情(即,context...>=>相当于Monad函数之间的组合运算(monadic function),这些函数输入普通值,输出monadic值。...因为applicative functor并不允许applicative value之间有弹性的交互 这,怎么理解?
从Monad实现来看,从左侧取出值a和附加信息w,将右侧函数应用到a上,并从结果取出值b和附加信息w',结果值为b,附加信息为w `mappend` w',最后用return包装结果返回m类型的值,作为...其中,共享环境指的是Maintaining variable bindings,即do block里的每一个monadic value,都共享这个大函数的参数,在function之间传值的含义类似于“取出他们未来的值...P.S.能够从共享环境中读取值,这也是称之为Reader Monad的原因 三.State Monad 除日志追踪、共享环境外,还有一类最常见的问题是状态维护 然而,有一些领域的问题根本上就是依赖于随着时间而改变的状态...这让我们在 Haskell 中可以容易地处理状态性的问题,并让其他部份的程序还是保持纯粹性。...五.Monad的魅力 Monad能够赋予计算一些额外的能力,比如: Writer Monad:能够把函数转换成带日志的版本,用来追踪执行过程,或者给数据变换添加额外的信息 Reader Monad:能够让一系列函数在一个可控的共享环境中协同工作
实际在函数式编程语言实现中,Maybe确实只是一个类型(称为代数类型),具体的一个值有具体类型Just或Nothing,就像数字可以分为有理数和无理数一样。...现在,如果我们有一个单子叫IO,并且它有如下表现: 图 64 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...关键领域应用 因为函数式编程状态少、代码简洁等特点,使得它在交互复杂、安全性要求高的领域有重要的应用,像Lisp和Haskell就是因上一波人工智能热而火起来的,后来也在一些特殊的领域(银行、水利、航空航天等...你仍然可以在.then函数中写纯粹的函数,也可以在.then函数中调用其他的Promise,这就和IO Monad的行为非常像。...相比于面向对象,这种方式在组合上更方便简洁,更容易把复杂度降低,比如面向对象中可能对象之间的相互引用和调用是没有限制的,这种模式带来的是思考逻辑的时候思维会发散。
前段时间学了下 Haskell,看完了《Haskell 趣学指南》,刷了一些题,《Real World Haskell》正在看。...最大的感受是,以前对 Functor、Applicative 和 Monad 的理解太片面了。...Functor 谈 Monad(单子) 之前还是要谈谈 Functor(函子),毕竟所有的 Monad 都是 Functor。...在范畴论中,函子是范畴间的一类态射(这个定义给我的直观感受是函子指的是 fmap 函数……),数学上的概念就不多说了,下面我们来看看 Haskell 中的 Functor。...这两条定律可以保证在一个函子值上执行 fmap 只会在它上面映射一个函数——不再做其他事情。
引言 Haskell不同于Scala,是一门纯函数式语言,它强制使用者使用函数式语法而没有妥协。 是一门强类型定义的静态类型语言。...你也能在Haskell中发现Clojure风格的惰性求值(lazyevaluation)以及与Clojure和Erlang相同的列表推导语法。...无副作用,通过monad概念保存状态:一个Haskell函数可以返回一个有副作用并且会被延迟执行的结果....Day1 逻辑 在OS X下安装Haskell环境:brew install haskell-platform 通过命令启动交互式环境:ghci 基本类型 {- basic type -} Prelude...匿名函数 (\param1.. paramn ->function_body) map map (\x -> x * x) [1, 2, 3] filter、foldl和foldr (reduce)
和一个函数,返回一个新的 monad。...monad 有专属的类型类——Monad,其定义如下: class Applicative m => Monad (m :: * -> *) where (>>=) :: m a -> (a ->...>>=前面说过了,>>有一个默认实现,就是把一个 monad 直接换成另一个 monad 返回,fail不会被主动调用,在一些特定语法结构中,会被 Haskell 用于模式匹配。...一个类型要成为 monad 不仅要满足 Monad 类型类的条件,还要满足 monad 定律(虽然编译器并不会帮你检查): 左单位元:return x >>= f 和 f x 等价 右单位元:m >>=...return 和 m 等价 结合律:(m >>= f) >>= g 和 m >>= (\x -> f x >>= g) 等价
实际在函数式编程语言实现中,Maybe确实只是一个类型(称为代数类型),具体的一个值有具体类型Just或Nothing,就像数字可以分为有理数和无理数一样。...现在,如果我们有一个单子叫IO,并且它有如下表现: 我们把这种类型的Monad称为IO,我们在IO中处理打印(副作用)。...关键领域应用 因为函数式编程状态少、代码简洁等特点,使得它在交互复杂、安全性要求高的领域有重要的应用,像Lisp和Haskell就是因上一波人工智能热而火起来的,后来也在一些特殊的领域(银行、水利、航空航天等...你仍然可以在.then函数中写纯粹的函数,也可以在.then函数中调用其他的Promise,这就和IO Monad的行为非常像。...相比于面向对象,这种方式在组合上更方便简洁,更容易把复杂度降低,比如面向对象中可能对象之间的相互引用和调用是没有限制的,这种模式带来的是思考逻辑的时候思维会发散。
在这个简单的例子中,这样的处理似乎没有什么问题,因为只有 labelTree 在修改 i,但是,如果放在一个更加复杂的场景中,这样做是有很大风险的。...但是,共享可变变量的实现中还有一个灵活之处,就是它可以很方便地获取和修改状态,例如,在给多棵树打连续的标签的过程中,我们可能需要在两棵树之间隔开一个标签,也就是说我们想在给一棵树打上标签后先令标签 +...前面提到了,副作用并不止是修改变量一种,它还包括有读写文件、读入用户输入、在控制台打印输出等等,总之,一个函数如果除了接收参数和返回结果之外做了任何事情,它都产生了副作用。...只不过 IO 所管理的状态不是一个变量而是程序与整个世界之间交互的所有 IO 操作。在 Haskell 中,IO Monad 是一个基础的 Monad 6。...但在 Haskell 中,并没有这样的方法,唯一能运行的方式是通过 main 运行,而 main 函数的类型就是 IO (),这样就保证了 Haskell 的「纯」。
写在前面 一直有个疑惑,Haskell号称纯函数式语言,那么铁定不纯的场景(肯定有副作用,或者操作本身就是副作用)如何解决?...Haskell的做法其实类似于React的componentDidMount()等组件生命周期函数,React建议(道德约束)保持render()是纯函数,带有副作用的操作挪到componentDidMount...圈定不纯环境类似于async function,I/O Action只能出现在do语句块中,这一点类似于await P.S.实际上,执行I/O Action有3种方式: 绑定给main时,作为入口函数...IO (FilePath, Handle) -- 定义在System.Directory模块中,用来删除指定文件 removeFile :: FilePath -> IO () -- 定义在System.Directory...模块中,用来重命名指定文件 renameFile :: FilePath -> FilePath -> IO () 注意,其中removeFile和renameFile都是System.Directory
♣ 题目部分 在Oracle中,表和表之间的关联方式有哪几种?...对于Oracle 6提供的群集连接(Cluster Join)和Oracle 8提供的索引连接(Index Join),本书不做介绍。...在Oracle数据库中有一个隐含参数“_OPTIMIZER_SORTMERGE_JOIN_ENABLED”控制着SMJ的启用和关闭,该参数默认值是TRUE,表示启用SMJ连接。...在嵌套循环连接中,Oracle读取驱动表(外部表)中的每一行,然后在被驱动表(内部表)中检查是否有匹配的行,所有被匹配的行都被放到结果集中,然后处理驱动表中的下一行。...在Oracle数据库中有一个隐含参数“_HASH_JOIN_ENABLED”控制着HJ的启用和关闭,该参数默认值是TRUE,表示启用HJ连接。
但的确每个 monad 都是 applicative functor,即使 Monad 并没有这么声明。 在 Monad typeclass 中定义的第一个函数是 return。...因为 applicative functor 并不允许 applicative value 之间有弹性的交互。他们最多就是让我们可以用 applicative style 来传递参数给函数。...do 表示法 Monad 在 Haskell 中是十分重要的,所以我们还特别为了操作他设置了特别的语法:do 表示法。...至于在 do 表示法中模式匹配失败的话,那就会调用 fail 函数。他定义在 Monad 的 type class 定义猪。...Haskell 允许任何型态是任何 type class 的 instance。但他不会检查单子律是否有被遵守,所以如果我们要写一个 Monad 的 instance,那最好我们确定他有遵守单子律。
---- 函数式编程的目标:使用函数来抽象作用在数据之上的控制流与操作,从而在系统中消除副作用并减少对状态的改变。...,在本章中_代表lodash对象。...定义如下: g :: A -> B //函数g输入A返回B f :: B -> C //函数f输入B返回C //那么f和g的组合 可以定义为一个函数输入f和g 生成一个可以输入A 直接变成C的函数...(val)); }; }; 函数式编程空值的处理:Functor和Monad。...msg.join().get();//-> 'HELLO MONADS!' Maybe Monad用来处理是否为空的判断逻辑。它有2个具体的类型:Just和Nothing。
领取专属 10元无门槛券
手把手带您无忧上云