使用 Trace 函数以 Haskell 的 do 表示法进行惰性求值

2023-12-01

我想知道为什么这个“调试消息 1”没有打印在这个片段中:

import Debug.Trace

main = do
    return (trace "debug message 1" ())
    trace "debug message 2" (return ())

第二个“调试消息2”被打印出来,但没有“调试消息1”。看来这两种表达方式是一样的。

我尝试将“调试消息1”绑定到一个变量,然后在另一个地方使用该变量,它实际上触发了评估并打印“调试消息1”,但我仍然不明白为什么会发生这种情况。

如果我翻转语句的顺序,结果仍然相同:

import Debug.Trace

main = do
    trace "debug message 2" (return ())
    return (trace "debug message 1" ())

“调试消息 1”永远不会被打印(使用 runhaskell)。


并没有什么特别的魔力do符号。

main = do
    return (trace "debug message 1" ())
    trace "debug message 2" (return ())

main = return (trace "debug message 1" ()) >>=
        \_ -> trace "debug message 2" (return ())

根据单子恒等律之一,return a >>= f = f a, so

main = (\_ -> trace "debug message 2" (return ()))
         (trace "debug message 1" ())

该函数忽略其参数,因此不计算该参数;表达式简化为

main = trace "debug message 2" (return ())

第一条消息完全消失了,你可以看到剩下的trace现在是必须减少评估的最外层应用程序main,因此将打印此消息。

当你翻转订单时,你得到了

main = do
    trace "debug message 2" (return ())
    return (trace "debug message 1" ())

这与

main = trace "debug message 2" (return ()) >>=
         (\_ -> return (trace "debug message 1" ()))

这里的情况有点复杂。首先trace(消息2)是被迫的,因为>>= for IO其左操作数是严格的。然后return ()被执行,什么也不做。它的值被忽略,最后的动作,return (trace "debug message 1" ())被执行。这也没有任何作用(return never做任何有趣的事情)。自年底以来mainaction 是程序的结束,这个返回值永远不会被检查,因此永远不会被强制,所以它不会被评估。有些人认为main应该要求有类型IO ()强调它的返回值从未被使用。 (我相信他们对此是错误的,因为永远运行的程序确实应该具有类型IO Void or IO a,但这是一个挑剔。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Trace 函数以 Haskell 的 do 表示法进行惰性求值 的相关文章

  • 嵌套在其他 monad 中的 IO 操作未执行

    我有一个 foobar IO ParseResult String String ParseResult 是一个在这里定义的 monad https hackage haskell org package haskell src exts
  • Haskell 排列库函数 - 请澄清一下?

    这是代码permutationsHaskell 中的函数Data List module permutations a gt a permutations xs0 xs0 perms xs0 where perms perms t ts i
  • Haskell cabal:我刚刚安装了软件包,但现在找不到软件包

    在这里 http haskell org haskellwiki Cabal Install I just installed packages 2C but now the packages are not found这是我可以找到我正在
  • 动态加载编译的 Haskell 模块 - GHC 7.6

    我正在尝试使用 GHC API 动态编译和加载 Haskell 模块 我知道 API 从一个版本到另一个版本波动很大 所以我专门谈论 GHC 7 6 我尝试在 MacOS 和 Linux 上运行相同的代码 在这两种情况下 插件模块都可以正常
  • 数据类型变体之间的转换

    假设我想创建一种数据类型的两种变体 一种具有特定的构造函数 另一种没有它 否则它们是相同的 我想出了这个 LANGUAGE KindSignatures LANGUAGE DataKinds LANGUAGE GADTs data Foo
  • 用纯函数式语言保持状态

    我正在尝试弄清楚如何执行以下操作 假设您正在开发直流电机的控制器 您希望让它以用户设置的特定速度旋转 def set point ref sp 90 while true let curr read speed controller set
  • 作为应用函子(Haskell / LYAH)

    第11章向你学习 Haskell引入以下定义 instance Applicative gt r where pure x gt x f lt gt g x gt f x g x 在这里 作者进行了一些不寻常的挥手 的实例实现有点神秘 所以
  • 系统地将函数应用于 haskell 记录的所有字段

    我有一条包含不同类型字段的记录 以及一个适用于所有这些类型的函数 举一个小 愚蠢 的例子 data Rec Rec flnum Float intnum Int deriving Show 比如说 我想定义一个为每个字段添加两条记录的函数
  • ~/.cabal/config 中的“共享”是什么意思?

    我想 共享 会让cabal install更快 对吧 共享的默认值为 False 我们应该使用 True 还是 False 来共享 thanks 这意味着 还构建动态链接 又名共享 版本的库 这些版本与cabal install cabal
  • 对参数进行排序以利用柯里化

    我最近两次重构代码以更改参数的顺序 因为代码太多 黑客喜欢flip or x gt foo bar x 42正在发生 在设计函数签名时 哪些原则可以帮助我充分利用柯里化 对于轻松支持柯里化和部分应用的语言 有一系列令人信服的论点 最初来自
  • Haskell 中是否可以部分应用第 n 个参数?

    我很好奇是否可以写一个函数apply nth它接受一个函数 参数的数量以及该参数的值 然后返回一个新的 部分应用的函数 我的感觉是 由于类型系统的原因 这是不可能的 但我无法给出令人满意的答案 我也无法提出工作类型签名 如果语言的类型更加松
  • 为什么 Kleisli 不是 Monoid 的一个实例?

    如果您希望附加两个类型 a gt m b 的函数 以便只得到一个附加两个结果的相同类型的函数 您可以使用 Kleisli 来执行此操作 instance Monad m Monoid b gt Monoid Kleisli m a b wh
  • 无法让 wxHaskell 在 Mac 上从 ghci 工作

    我正在尝试跑步一个例子 http www haskell org haskellwiki WxHaskell Quick start Hello world in wxHaskell using EnableGUI function htt
  • 使用 Parsec 解析数据并省略注释

    我正在尝试编写一个 Haksell Parsec 解析器 它将文件中的输入数据解析为 LogLine 数据类型 如下所示 Final parser that holds the indvidual parsers final Parser
  • 在 Haskell 中使用 Maybe 类型

    我正在尝试利用 Haskell 中的 Maybe 类型 我有一个查找返回 Maybe 的键 值元组 如何访问 Maybe 包装的数据 例如 我想将 Maybe 包含的整数与另一个整数相加 或者 您可以进行模式匹配 case maybeVal
  • 优化计算 200 万以下所有素数总和的 Haskell 代码

    欧拉计划中的问题 10 我在那里看到了一些讨论 但仅限于 C 我用下面的代码来计算 print sum sieve 2 2000000 where sieve sieve x xs x sieve filter 0 mod x xs 需要很
  • 自动函子实例

    给定以下代数类型 ghci gt data Foo a Foo a 然后我实例化其中之一 ghci gt let f Foo foo 最后 我想打电话给fmap将函数应用为 a gt b gt Foo a gt Foo b ghci gt
  • Haskell - 让函数返回空字符

    我正在尝试创建一个函数来删除字符串中的每个第 n 个元素 dropEvery String gt Int gt String dropEvery str n map char indx gt if indx mod n 0 then cha
  • 数据记录的类约束

    我有一个data type data BuildException a KillBuild JobID a Stage FailBuild JobID a Stage CancelBuild JobID a Stage StopBuild
  • Haskell 程序查找列表中元素的位置

    我需要编写一个函数来查找列表中一个特定元素的位置 我是这样写的 findPos list elt list 1 head list elt 0 otherwise 1 findPos tail list elt 但是如果列表中元素重复怎么办

随机推荐

  • 无法在 Node.js 上使用 sqlite3 将行放入数组中

    我在 Node js 中有一段代码 它从 SQLite 数据库中选择所有内容并打印每一行 它可以工作 代码如下 var sqlite3 require sqlite3 verbose var db new sqlite3 Database
  • Braintree 中出现“请求已中止:无法创建 SSL/TLS 安全通道”错误

    在我的本地 PC Braintree 中 执行时显示错误 请求已中止 无法创建 SSL TLS 安全通道 var clientToken gateway ClientToken generate 我正在使用 Braintree 2 33 0
  • Ruby 中变量前的感叹号

    通过 ruby Monk 他们偶尔会从左侧字段中抛出一段具有不熟悉语法的代码 def compute xyz return nil unless xyz xyz map a b b nil a b a end 谁能解释一下这三种用途吗 1
  • Sequelize 不创建模型关联列

    当 Sequelize 创建关联字段时 我有点困惑 我已经使用sequelize cli 创建了我的迁移 这生成了迁移和模型文件 然后在模型文件中我填充了我的关联 然后跑了npx sequelize cli db migrate 这将创建表
  • m2e eclipse插件如何与eclipse交互?

    我是一个 Eclipse 强者 由于历史上 Maven Eclipse 集成不佳而忽略了 Maven m2e 似乎正在成熟 我正在认真试驾它 我想了解 m2e 在 eclipse 中是如何工作的 这样我就可以更好地让两者顺利地协同工作 并了
  • 根据以编程方式创建时间表更改运输车队

    在跟进我之前的问题时上一个问题 当以编程方式创建时间表时 我在主程序启动时运行该函数 参见图 1 我想基于此更改 Transporterfleet image2 时间表 但是 当我通过 initschedule 函数执行此操作时 会给出下一
  • Scikit Learn 的 Keras 包装器 - AUC 评分器不起作用

    我正在尝试使用Keras Scikit 学习包装器以便更容易地随机搜索参数 我在这里写了一个示例代码 其中 我生成一个人工数据集 我在用moons from scikit learn from sklearn datasets import
  • mysql触发器怎么写

    有两张桌子表A 如果用户使用此查询 插入 A 值 abc 1 50 那么触发器应该检查 表B 中的student name 如果student name已经存在于 表B 中 那么 更新表 B 中的 all marks 字段 例如 all m
  • Kivy - 在 .py 文件中使用一个屏幕的 TextInput 中的文本到另一个屏幕

    我的第一个屏幕上有一个 TextInput 我想在第二个屏幕上的标签中使用收到的文本 我怎样才能做到这一点 由于可能有不同的玩家 我创建了一个玩家类 它为每个玩家存储一个名字和他 她的分数 在第二个屏幕中 我还尝试创建一个可以编辑点 标签文
  • 如何从文件中读取powershell表

    我在一个文件中有这样的内容 File Versions aaa 1 0 0 123 1 0 0 124 bbb 1 0 0 123 1 0 0 124 如何在powershell中将其读入表或类型数组 我已经通过以下脚本创建了该文件 ver
  • 将 javascript 函数注入到 Iframe 中

    这个链接 存档版本 描述了如何将脚本中的代码注入到 iframe 中 function injectJS var iFrameHead window frames myiframe document getElementsByTagName
  • 如何永远隐藏视图

    有人可以告诉我如何永远隐藏视图吗 我正在隐藏一个视图view setVisibility view GONE 但是当重新打开应用程序时 我必须重新隐藏视图 我希望在单击按钮时始终隐藏视图 直到清除应用程序数据或卸载 谢谢 您需要通过创建隐藏
  • LWP::UserAgent 和 500 SSL 协商失败

    我正在运行一个旧的 Debian 服务器 每天一次通过 Perl 脚本获取网页 从昨天开始 脚本失败并出现 500 SSL 协商失败 错误 use strict use LWP UserAgent my browserObj LWP Use
  • jQuery 验证插件:仅接受德文字母

    我正在寻找 jquery 验证插件的方法 http bassistance de jquery plugins jquery plugin validation 只接受字母 包括德语所谓的 Umlaute 我用谷歌搜索了一下 但不幸的是找不
  • 如何在控制台应用程序中添加 C# 登录尝试循环?

    我是这门语言的新手 我尝试了一些方法 但无法弄清楚如何设置登录循环以使用最大登录尝试次数 3次 有人可以帮我吗 static void Main string args Console WriteLine Status status Ona
  • 如何在按下按钮后在 JQuery / ASP.NET 中创建淡入淡出标签

    我认为这应该很容易 但我不太确定如何连接 我有一个页面 用户可以在其中定义查询 完成后 用户输入查询的名称并按下按钮 我想处理按钮单击 使文本标签 或跨度 可见几秒钟 然后让它淡出 由于它是回发 我可以将 ASP Label 控件变为可见
  • 仅从特定活动中读取 NFC 标签

    我先告诉你我在做什么 我按顺序进行了三项活动 活动1 gt gt 活动2 gt gt 活动3 现在 当我点击标签时 我只想从 Activity2 读取 NFC 标签 当我处于 Activity1 或 Activity3 中时 我的应用程序应
  • 如何将父组件注入子组件?

    我正在尝试将父组件注入子组件中 我认为这很简单 只需在子组件中指定 注入父组件constructor constructor private parent AppComponent child component constructor 我
  • 限制文本框中的数字和字母 - C#

    我想限制可以在文本框中输入的数字和字母 假设我只想允许数字 0 5 和字母 a d 小写和大写 我已经尝试使用屏蔽文本框 但它只允许我指定数字 字母 均无限制 或数字和字母一起但按特定顺序 最好的情况是 用户尝试输入数字 6 但文本框中没有
  • 使用 Trace 函数以 Haskell 的 do 表示法进行惰性求值

    我想知道为什么这个 调试消息 1 没有打印在这个片段中 import Debug Trace main do return trace debug message 1 trace debug message 2 return 第二个 调试消