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

2个使用do符号的类似Haskell函数返回相同的结果,但其中一个被多次调用

这个问答内容涉及到函数的纯度和惰性求值的概念。

纯函数是指在相同的输入下,总是返回相同的输出,并且没有任何副作用。副作用包括但不限于修改全局变量、修改输入参数、调用其他非纯函数等。

惰性求值是指只在需要的时候才进行计算,而不是立即计算。这可以提高性能和资源利用率。

下面是两个使用do符号的类似Haskell函数返回相同结果的示例:

函数1:

代码语言:txt
复制
do
  x <- computeX
  y <- computeY
  return (x + y)

函数2:

代码语言:txt
复制
do
  xy <- do
    x <- computeX
    y <- computeY
    return (x, y)
  return (fst xy + snd xy)

这两个函数都使用了do符号来组合多个计算步骤。它们的返回结果都是计算x和y的和。

这两个函数的区别在于函数1是按顺序计算x和y,而函数2是先将x和y计算出来,然后再进行求和。函数2使用了惰性求值的思想,只在需要的时候才计算x和y,可以避免重复计算。

这两个函数的应用场景取决于具体的业务需求和计算逻辑。如果计算x和y的过程比较复杂且耗时,可以选择函数2来避免重复计算。如果计算x和y的过程比较简单且耗时不大,可以选择函数1。

腾讯云相关产品和产品介绍链接地址:

请注意,以上链接仅供参考,具体选择产品应根据实际需求和情况进行评估。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Parser Combinator

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

1.3K20

铁定不纯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代码是相当混乱。...HaskellIO函数都会返回一个IO Monad,而上面的代码中,我们并没有对每一条都使用之前结果。对于部分IO Monad(如putStrLn返回),我们直接就抛弃了这些返回值。...上下文指就是之前产生运算结果,也就是Do表记中类似“变量”东西。而没了上下文,这就意味着Applicative失去了根据之前运算结果进行下一步运算能力。...在调用形式上看,>>=左侧是之前运算结果,而右侧通过λ参数将这个结果引入了进来,以供之后使用。但是左侧与右侧并没有联系,因此之后运算是无法依赖于之前运算

78110

基础语法_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.8K30

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

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

52550

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

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

3K30

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

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

98610

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

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

1.3K10

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 值。

15210

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

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

9410

从素数生成看Haskell简洁性

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

30410

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

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

1.4K40

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

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

58320

详细解答!从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提供了丰富函数对其处理,具体可以参考文档。

85430

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
领券