首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Parser Combinator

首先,expression 将依次尝试使用解析不同表达式的 parser 来解析输入文本,其中一种表达式是函数调用,用 functionCall 表示。...其中使用到了 between 组合子,它用来构建一个被另外两个 parser 包裹的 parser。...将一个 parser 应用零次到多次的实现可以是:如果能够应用一次到多次,我们就直接使用 some,如果失败,就直接返回空列表。...,这个函数不断使用原 parser 来解析输入字符串,如果解析成功,就将解析结果记录在一个列表里,同时累积了移动的总字符数,当解析失败时就将这个结果返回。...这常常导致多个系统中存在大量功能类似而不尽相同的模块,结果是到了相当长时间后发现太过混乱,不得不进行大规模重构,抽取相似模块共用。

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

    铁定不纯的IO_Haskell笔记5

    Haskell提供了do语句块,也是用来隔离不纯的部分的 一.I/O action 先看个函数类型: > :t print print :: Show a => a -> IO () print函数接受一个...,都是接受一个具体类型参数,返回具体类型(比如IO ()) P.S.其中,newtype与data类型声明类似,语法和用法也都基本相同,newtype是更严格的类型声明(直接换成data也能正常用,data...line变量,为空则什么都不做(返回IO (),结束),否则把该行内容通过putStrLn输出到标准输出并换行,并递归执行main 其中,main表示入口函数(与C语言类似),do用来把多个I/O Action...合并成一个,返回被合并的最后一个I/O Action。...[1, 2, 2] 1 2 2 [(),(),()] mapM_与之类似,但丢弃结果,返回IO (),很适合print等不关心I/O Action结果的场景: > mapM_ print [1, 2,

    1.3K30

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

    Haskell中全符号的、被小括号包裹的函数默认是中缀的,比如这个函数的调用就是中缀形式f xs。接受一个容器内的函数和值,并将运算之后的结果重新放在容器中。...Do-notation Do表记(do-notation)是Haskell给Monad操作提供的语法糖。在不使用Do表记情况下,使用Monad的代码是相当混乱的。...Haskell中的IO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前的结果。对于部分IO Monad(如putStrLn返回的),我们直接就抛弃了这些返回值。...上下文指的就是之前产生的运算结果,也就是Do表记中的类似“变量”的东西。而没了上下文,这就意味着Applicative失去了根据之前运算结果进行下一步运算的能力。...在调用形式上看,>>=的左侧是之前的运算结果,而右侧通过λ参数将这个结果引入了进来,以供之后使用。但是的左侧与右侧并没有联系,因此之后的运算是无法依赖于之前的运算的。

    81310

    基础语法_Haskell笔记1

    Haskell的特点: 变量不可变:函数式里的变量与常量概念一样,源自数学思维,令x=1,那么x永远都是1 引用透明:函数调用能被直接替换成相应的值,而不会影响函数的行为。...语法格式 Haskell里的函数调用默认是前缀语法,例如: succ 2 min 1 (-2) 与Bash脚本的函数调用语法一样,函数名 参数1 参数2 但运算符作为特殊的函数,默认要以中缀形式调用,...(/) :: Fractional a => a -> a -> a函数的不全调用(partially applied),所以没有得到计算结果,而是返回了函数(/ 2) :: Fractional a...参数列表后面多了| 条件表示不同的函数体分支,被调用时满足条件就执行对应函数体并返回,否则就按顺序依次向下检查 注意,最后的otherwise比较有意思,因为: > :i otherwise otherwise...用expression依次尝试匹配pattern,匹配成功就执行对应的代码块并返回结果,否则尝试下一个,都不匹配就报错 P.S.同样,作为表达式,case-of可以用于任何地方,比模式匹配灵活得多(模式匹配只能用于函数声明

    1.9K30

    从 Java 和 JavaScript 来学习 Haskell 和 Groovy(类型系统)

    代码中,变量 o 发生了多次赋值,并且每次赋值的类型都不相同。...其中的 ClosureParams 注解,用以明确告知 predicate 闭包将返回布尔类型,并且闭包接受的参数与闭包调用者的 “第一个参数” 一致,即 Person 类型。...在 Java、C++这样的静态语言中,函数只能被声明和调用,只能依附在类的定义上面,无法像对象一样被传来传去,为此还孕育了一堆设计模式,看起来高大上了,其实是无奈为之。...比如,函数的定义方式给了两种,一种是直接声明,一种是表达式赋值,但是这两者被解释器处理起来的机制并不相同;再比如,函数的所谓 “构造器” 是和函数本身融合在一起的,不像 C++或者 Java 里面,类定义是一方面...里面的泛型参数啊,但又有很大区别,因为这里指规定了函数参数或者返回的取值类型,并没有约定 “值”——这里参数和返回都是 “a”,但是实际传入的参数和返回值却一般都是不相同的,只是类型相同而已。

    55150

    Kotlin版图解Functor、Applicative与Monad

    那么扩展一下,我们说任何值都可以放到一个上下文中。 现在你可以把上下文想象为一个可以在其中装进值的盒子: ? 现在,将一个函数应用到这个值上时,会根据上下文的不同而得到不同的结果。...另外 Kotlin 有自己的表达可选值的方式,并非使用 Maybe 类型这种方式,参见空安全。 Functor 当一个值被包装在上下文中时,你无法将一个普通函数应用给它: ?...Monad 将一个返回已包装值的函数应用到一个已包装的值上。 Monad 有一个函数 ))=(在 Haskell 中是 >>=,读作“绑定”)来做这个。 让我们来看个示例。...注: Kotlin 内置的空安全语法可以提供类似 monad 的操作,包括链式调用: fun Int?.half() = this?....contents 它可以在 Kotlin 中模拟(其中 Haskell 的 被替换为 (- 属性与赋值操作)如下: fun `do` (ioOperations: () -> IO

    1.2K20

    泛型和元编程的模型:Java, Go, Rust, Swift, D等

    困难在于我们写的每一个函数和类型定义都只对那些大小相同、复制方式相同、行为相同的数据有效。 如何解决这个问题?...这样运行效率足够快,但代价是代码大小和编译时间的膨胀,因为同样的代码只要稍加调整就会被编译多次。在C语言中,这相当于在一个宏中定义你的整个数据结构,并为在使用该结构的地方调用该宏。...该代码确认了这样的关系:返回类型与列表类型相同,但可以是任何类型。 接口 基础装箱方法的另一个限制是,装箱类型是完全不透明的。...这种方法在某种程度上类似于在调用时构造Go式的接口对象,只是将函数指针表作为一个隐藏的参数传递,而不是作为现有的参数之一打包在一起。...这种方式虽然被Haskell类型类使用,但GHC(GHC是Haskell编译器)通过内联和特殊化,也可以做单态化优化。

    3.1K30

    沅有芷兮:类型系统的数学之美

    我们所处的世界往往是鱼与熊掌不可兼得 —— Haskell 长于类型系统,但让程序员失去了对数据在内存中如何排布的控制;C 长于对数据在内存中的精确控制,但没有一个像样的类型系统。...我们要么设计一种新的数据类型 non_zero_f64 把零从中排除出去(这在大多数语言里都很困难),从输入的角度让这个函数的 type signature 完备;要么让返回的结果是一种特殊的类型,它可能是...函数的返回值依旧是 f64,但除零的时候会抛出异常。对于支持异常的语言,除了上一种方式,我们还可以抛出异常。...第二种方式也是对类型完备性的一种损伤,因为调用者需要知道并且选择处理或者不处理那些「意外」。因为意外不是返回类型的一部分,所以,额外的逻辑是必不可少的。 上面 div 函数的问题只是冰山的一角。...这个函数可以被 pipe,被 compose,调用者不必担心类型的泄露 —— 所有信息都已经在 type signature 里面了,编译器可以做更合适更严格的检查,也可以适当优化 —— 更重要的是,围绕着这个类型

    1K10

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

    原始数组的左边处理完毕,右边类似,不再赘述 勉强能解决问题,但存在几个缺陷: 日志输出混在结果里,日志看起来不很直观 日志会影响原结果输出,缺少隔离 只能打印输出,没办法收集起来进一步处理,不够灵活 那么...一个函数也可以被想做是包含一个context的。这个context是说我们期待某个值,他还没出现,但我们知道我们会把他当作函数的参数,调用函数来得到结果。...(x),返回一个函数(\_ -> x),该函数接受一个参数,忽略掉并返回之前传入的任意值。...k (f r)同理,把从f取出的值喂给k,返回一个具有函数context的东西,最后把参数r喂给它,得到最终结果 好了,function现在是Monad了,那它有什么用?...其中,共享环境指的是Maintaining variable bindings,即do block里的每一个monadic value,都共享这个大函数的参数,在function之间传值的含义类似于“取出他们未来的值

    1.5K40

    为什么 Haskell 是我们构建生产软件系统的首选

    例如,a -> b -> a 的签名告诉我们这个函数接收两个任意类型的参数,并返回一个类型与第一个参数相同的值。假设我们要检查一个元素是否在某个列表中。...(例如,具有给定参数列表的函数调用)的属性。...那么,纯度是说 Haskell 程序不会产生副作用吗?当然不是,但这确实意味着副作用被推到了我们系统的边缘。...虽然我们最后还是要手动验证代码结果,例如在浏览器中刷新页面或使用工具来验证 JSON 端点,但许多这样的操作可以推迟到编程会话结束时进行。...例如,当一个函数将一个元素添加到一个列表时将返回一个新列表,并且旧列表使用的内存将由垃圾回收器释放。这种不变性的好处是它简化了并发编程。

    1.4K10

    Haskell 实现京东优惠券爬取的详细步骤解析

    然后,利用 fromDocument 函数将响应内容解析为文档树,并返回给调用者。3. 解析页面内容获取优惠券信息通过查看京东优惠券页面的 HTML 结构,我们可以找到优惠券的相关信息所在的位置。...以下是一个简单的示例函数:import qualified Data.Text as TgetCouponKeys :: Cursor -> [T.Text]getCouponKeys doc = do...最终将所有的 key 值作为一个列表返回。4. 整合代码并运行爬虫程序最后,我们将上述函数整合到一起,并编写一个主函数来运行整个爬虫程序。...函数获取页面内容的文档树,然后调用 getCouponKeys 函数提取出所有优惠券的 key 值,并输出到控制台。...最后,我们使用 mapM_ 函数将 key 值逐行打印出来。5. 运行结果分析当我们运行该程序时,它会发送 HTTP 请求获取京东优惠券页面的内容,并从中提取出所有优惠券的 key 值。

    29210

    Haskell 实现京东优惠券爬取的详细步骤解析

    然而,想要及时获取最新的京东优惠券信息并非易事,尤其是在优惠券数量庞大的情况下。为了解决这一问题,我们可以利用 Haskell 编程语言编写一个简单而高效的爬虫程序,用于自动获取京东优惠券的信息。...然后,利用 fromDocument 函数将响应内容解析为文档树,并返回给调用者。 3. 解析页面内容获取优惠券信息 通过查看京东优惠券页面的 HTML 结构,我们可以找到优惠券的相关信息所在的位置。...最终将所有的 key 值作为一个列表返回。 4. 整合代码并运行爬虫程序 最后,我们将上述函数整合到一起,并编写一个主函数来运行整个爬虫程序。...函数获取页面内容的文档树,然后调用 getCouponKeys 函数提取出所有优惠券的 key 值,并输出到控制台。...最后,我们使用 mapM_ 函数将 key 值逐行打印出来。 5. 运行结果分析 当我们运行该程序时,它会发送 HTTP 请求获取京东优惠券页面的内容,并从中提取出所有优惠券的 key 值。

    14410

    从素数生成看Haskell的简洁性

    核心函数就是sieve,大致处理过程是这样:读入一个列表,并取出第一个元素p。然后筛选出不能被p整除的剩余数字,递归求解。这里提及一下,[2..]是Haskell列表的一个神奇的特性,即支持无限列表。...,这段代码的结果并不是一个内容为2-maxn内素数的数组,而是记录2-maxn间的数字是不是素数的一个布尔数组。...不过其算法本质还是和CPP版本相同。 百度的时候还发现了大牛廖雪峰的另一种操作,即采用generator的形式构造一个序列并filter。...其中,tail想到与后移整个数列,之后通过zipWith函数的处理将两个数列相加,以此来达到F(n)=F(n-1)+F(n-2)的效果。...虽然说这样高度精简的代码由于不直观,并不太适合在实际的项目中使用,况且其他语言的稍长的代码甚至可能在效率上更优,但这仍不影响Haskell表现其独有的简洁及优雅的魅力。

    33710

    【笔记】《C++Primer》—— 第一部分:C++基础

    (),std::end()函数,可以给数组使用并返回类似上面迭代器的指针 两个指针相减得到地址差的类型是ptrdiff_t的类型,也是有符号数。...=42){;},这样又完成了赋值又完成了检验还增强了可读性 复合赋值运算符,也就是+=,-=之类的符号,只会进行一次赋值求值,效率比两行赋值符高一点点 自增自减有前置和后置两个版本,其中后置版本会返回原来的值然后将值加...what函数来得到异常的信息,详细回到5.6可以查看 6 函数 建议函数的声明与定义要分开来写,因为函数可以声明多次但只能定义一次,声明建议写在头文件中 函数形参可以是引用类型,此时传入的实参称为引用传递或传引用调用...传递数组的引用时,注意由于引用必须要有实体,所以需要保证输入的数组大小与形参指定的大小相同 main函数可以带有两个参数,argc和argv,其中argc是命令行调用此程序时附带传入的参数数量,argv...auto的函数,然后在声明后面用箭头号->指出真正的返回类型 const_cast类型转换在重载中非常有效,主要用于先将函数主干用const写完,然后重载一个普通版本的函数,其中传入的参数都利用const_cast

    1.5K40

    听君一席话,如听一席话,解释解释“惰性求值”~

    这,就,是, —— 惰性求值的思想体现(不需要立即返回的值,就先别计算;) 庐山面目 来看下 wiki 释义: 惰性求值又叫惰性计算、懒惰求值,也称为传需求调用,是一个计算机编程中的一个概念,目的是要...在使用惰性求值的时候,表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值。 这句话很重要!怎么理解?...引用 Reincarnation 的回答: 通过将表达式包装成一个thunk实现的; 例如计算f (g x),实际上给f传递的参数就是一个类似于包装成(_ -> (g x))的一个thunk;...然后在真正需要计算g x的时候才会调用这个thunk; 事实上这个thunk里面还包含一个boolean表示该thunk是否已经被计算过(若已经被计算过,则还包含一个返回值),用来防止重复计算;...(思路:强制求值第一个参数,返回第二个参数;) 函数式语言和命令式语言的内存模型; 懒惰奥义 听君一席话,如听一席话,希望看完本篇后,有人再问你“什么是惰性求值”,能心里有个基本的谱~~ 人天性爱偷懒

    66120

    详细解答!从C++转向Rust需要注意哪些问题?

    但Rust在这里做得更完善一些,体现在: 相同的子类型可以因为Tag的不同出现多次,如上面的Write和Send,子类型都是String。...match会要求分支覆盖enum所有变体,std::visit也会在编译期检查完整的类型覆盖,但其中类型会考虑C++的隐式类型转换,使用时需要小心。...学习Haskell对理解Rust也会很有帮助。 最后说明一下,在C++17中加入的std::optional实现了类似的功能。...Adapter在Rust中指的是一类函数,它们接收一个Iterator并且返回一个Iterator。这样的接口规范使用可以通过链式调用的方式组合多个Adapter完成复杂的功能。...类似地,也可以使用fold进行有初值的规约。 可以看到,针对迭代器,Rust提供了丰富的函数对其处理,具体可以参考文档。

    95930

    shell编程基础入门

    | 管道符号 将符号前面执行的结果作为符号后面的命令。如cat test.txt |wc -l 计算文档行数。 $变量前面表示符号。还有一个妙用即和!结合起来使用。!...& 如果把一条命令放到后台执行的话,则需要加上这个符号, 通常用作一个命令运作时间非常长的情况。如。Sleep 200 & 后台执行。Jobs 查看 bg 调用到前天 fg调用到后台。...例如,第一个参数是$1,第二个参数是$2。$#传递给脚本或函数的参数个数。$*传递给脚本或函数的所有参数。$@传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。...每一行加个#符号太费力了,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。...其功能是按用户指定的格式,把指定的数据显示到显示器屏幕上。在前面的例题中我们已多次使用过这个函数。

    1.3K40

    一篇文章从了解到入门shell

    执行并获取返回结果,有点类似JavaScript 的eval函数。 #!/bin/bash dt=`date` #反引号内的字符串会当作shell执行 ,并且返回结果。...后台运行的最后一个进程的ID号 $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。...所以我们可以写一个代码参数,返回值的函数 out(){ echo "全部参数$*" for item in $* do echo "$item" done return...n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 除了参数可以使用特殊符号,也可以使用上文中函数所使用的特殊符号,这里不再赘述 echo "执行的文件名:$0";...5.2、tail 类似上面的例子,我们要验证程序是不是在后台,每一秒输出一个数字到文件,使用cat读取,需要不断的多次查看,一次cat只能输出一次。

    2.1K30

    Julia(函数)

    请注意,结果是一个通用函数,但具有基于连续编号的编译器生成的名称。 匿名函数的主要用途是将其传递给以其他函数为参数的函数。...如果它接受关键字参数,可能的调用可能类似于plot(x, y, width=2),其中我们选择仅指定线宽。请注意,这有两个目的。该调用更易于阅读,因为我们可以用其含义标记一个自变量。...,如varargs函数中所示: function f(x; y=0, kwargs...) ### end 在中f,kwargs将是一个(key,value)元组集合,其中每个元组key都是一个符号...类似地,do a,b将创建一个包含两个参数的匿名函数,而平原do将声明其后是形式为的匿名函数() -> ...。 这些参数的初始化方式取决于“外部”功能。...(X))等于broadcast(x -> sin(cos(x)), X),类似于[sin(cos(x)) for x in X]:类似:仅存在一个循环X,并且为结果分配了一个数组。

    2.8K20
    领券