“foldp”是否违反了 FP 的不可变状态原则?

2024-03-23

我正在学习 Elm七周内增加七种语言 http://pragprog.com/book/7lang/seven-more-languages-in-seven-weeks。下面的例子让我很困惑:

import Keyboard
main = lift asText (foldp (\dir presses -> presses + dir.x) 0 Keyboard.arrows)

foldp定义为:

Signal.foldp : (a -> b -> b) -> b -> Signal a -> Signal b

在我看来:

  • 累加器的初始值presses只是0在第一次评估时main
  • 第一次评估后main看来初始值presses是函数的结果(a -> b -> b), or (\dir presses -> presses + dir.x)在这个例子中,是之前的评估。

如果确实如此,那么这是否违反了函数式编程原则,因为 main 现在维护内部状态(或者至少foldp does)?

当我使用时这是如何工作的foldp在我的代码中的多个地方?它是否保留多个内部状态,每次使用时一个?

我看到的唯一的其他选择是foldp(在示例中)从 0 开始计数,也就是说,每次评估时,都会以某种方式折叠由Keyboard.arrows。在我看来,这是极其浪费的,并且肯定会在长时间运行时导致内存不足异常。

我在这里错过了什么吗?


怎么运行的

Yes, foldp保留一些内部状态。保存整个历史记录将是一种浪费,而且还没有完成。

如果你使用foldp在代码中多次执行不同的操作或具有不同的输入信号,那么每个实例将保持其自己的本地状态。例子:

import Keyboard

plus  = (foldp (\dir presses -> presses + dir.x) 0 Keyboard.arrows)
minus = (foldp (\dir presses -> presses - dir.x) 0 Keyboard.arrows)
showThem p m = flow down (map asText [p, m])
main  = lift2 showThem plus minus

但是,如果您使用来自 Foldp 的结果信号两次,则编译后的程序中将只有一个 Foldp 实例,所产生的更改将仅在两个位置使用:

import Keyboard

plus  = (foldp (\dir presses -> presses + dir.x) 0 Keyboard.arrows)
showThem p m = flow down (map asText [p, m])
main  = lift2 showThem plus plus

主要问题

如果确实如此,那么这是否违反了函数式编程原则,因为 main 现在维护内部状态(或者至少foldp does)?

函数式编程没有任何人人都使用的伟大规范定义。有许多允许使用可变状态的函数式编程语言的示例。其中一些编程语言向您表明值在类型系统中是可变的(您可以看到 Haskell 的State a输入这样的内容,但这实际上取决于您的观点)。

但什么是可变状态呢?什么是可变值?它是程序内部的一个值,是可变的。也就是说,它可以改变。不同的时间可能有不同的事情。啊,但我们知道 Elm 如何称呼随时间变化的值!那是一个Signal.
所以真的是一个Signal在 Elm 中是一个可以随时间变化的值,因此可以被视为变量、可变值或可变状态。只是我们非常严格地管理这个值,只允许对Signals。这样一个Signal可以基于其他Signals 在你的程序中,或者来自图书馆或者来自外部世界(想想像这样的输入Mouse.position)。谁知道外界是如何得出这个信号的!所以允许你自己的Signals 基于过去的值Signals其实还可以。

结论/TL;DR

你可以看到Signal作为可变状态的安全包装。我们假设来自外界的信号(作为程序的输入)是不可预测的,但因为我们有这个仅允许 lift/sample/filter/foldp 的安全包装器,所以您编写的程序是完全可预测的。副作用是被包含和管理的,因此我认为它仍然是“函数式编程”。

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

“foldp”是否违反了 FP 的不可变状态原则? 的相关文章

  • 访问Scheme中的调用堆栈深度

    为了演示尾递归的有效性 我想要一种在Scheme中动态访问调用堆栈深度的方法 有没有办法做到这一点 如果没有 有没有办法在其他主要函数语言 OCaml Haskell 等 中做到这一点 Racket 允许您在调用堆栈中存储值 您可以使用它来
  • 在 Dart 中将类型化函数作为参数传递

    我知道Function https api dartlang org stable 1 22 1 dart core Function class html类可以作为参数传递给另一个函数 如下所示 void doSomething Func
  • Elm 组件和视图:什么时候应该使用 `Html msg` 以及什么时候应该使用 `Html Msg`

    我正在做一个项目 我和我的队友正在讨论哪种方法更好 在我看来Html msg似乎更通用 所以我认为我们应该尽可能使用它 但除此之外我不能给他其他理由 另外 我来自 React 和 Redux 对我来说看起来像是带有签名的组件Html Msg
  • 将其参数应用于自身的函数?

    考虑以下 SML 函数 fn x gt x x 这会产生以下错误 新泽西州标准 ML v110 72 stdIn 1 9 1 12 Error operator is not a function circularity operator
  • 任何遍历嵌套字典的函数式编程方法?

    我正在尝试找到更好的方法来实现这一点 d a b c 4 l a b c for x in l d d x print d 4 我正在学习函数式编程 所以我只是尝试随机出现的例子 Use reduce http docs python or
  • 如何在 React Native ListView 中将项目居中?

    我试图在选择一个项目时将其置于水平列表视图的中心 我当前的策略是首先测量项目并滚动到视图中引用项目的 x 坐标 目前 每当我按下某个项目时ListView滚动到最后x 538 有没有更简单的方法来实现这一点 同时保持代码无状态 功能 con
  • 未确定的泛型类型在 ghci 的运行时中如何表示

    我很清楚通用函数和通用数据类型 在泛型类型中 data SB forall x show x gt SB x instance Show SB where show SB x show x 所以对于任何给定类型x 如果它有一个签名Show
  • Haskell 将两个列表中不同索引处的元素组合起来

    对这个糟糕的标题表示歉意 我不太确定如何用语言描述它 但这就是我的意思 如果您知道更好的表达方式 请告诉我 假设我有 2 个长度相等的列表 a b c x y z 我想创建列表 a y z b x z c x y 本质上 对于 list1
  • D 中的特征可以用于类型类吗?

    我是 D 新手 我正在寻找一种使用类似 Haskell 的类型类进行编程的好方法 例如D 中的函子 幺半群等 Tango 或 Phobos 中是否实现了类似的功能 我听说过可以对某些属性进行编译时类型检查的特征 它们可以用于类型类吗 我尝试
  • 是否可以有效地计算 lambda 演算项?

    我最近用 lambda 演算编写了很多程序 我希望能够实时运行其中一些程序 然而 尽管趋势函数范式基于 lambda 演算和 B 约简规则 但我找不到一个不是玩具 不以效率为目的的评估器 函数式语言应该很快 但我所知道的那些语言实际上并不提
  • Scheme/Lisp 嵌套循环和递归

    我正在尝试解决方案中的一个问题 该问题要求我使用嵌套循环或嵌套递归 例如我有两个列表 我必须检查它们的笛卡尔积的条件 解决这些类型问题的最佳方法是什么 有关如何简化这些类型的函数的任何指示吗 I ll elaborate a bit sin
  • 为什么 x = x +1 在 Elixir 中有效?

    我读到的有关 Elixir 的所有内容都表明 赋值应该被视为模式匹配 如果是这样 为什么 x x 1 在 Elixir 中有效 不存在 x x 1 的 x 值 我读到的有关 Elixir 的所有内容都表明 赋值应该被视为模式匹配 在长生不老
  • 计算 python 字典/数组数据结构的非空尾叶 - 递归算法?

    我正在寻找一个函数来查找一种复杂字典 数组结构的所有非空端点 我认为因为我不知道嵌套数组的数量或它们的位置 所以它必须是递归的 而我只是还没有完全理解这种思维方式 所以对于嵌套字典 x top middle nested value nes
  • 如何使用 swift flatMap 从数组中过滤掉选项

    我对 flatMap 有点困惑 添加到 Swift 1 2 假设我有一些可选类型的数组 例如 let possibles Int nil 1 2 3 nil nil 4 5 在 Swift 1 1 中 我会做一个过滤器 然后是一个像这样的地
  • 使用 ocaml List.fold_left 列表中的最后一个元素

    我可以通过以下代码找到列表的最后一个元素 let last xs a list a let rec aux xs prev match xs with gt prev x ys gt aux ys x in match xs with gt
  • python函数返回函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 单位安全平方根

    我只是想知道如何以与 F 正确交互的方式编写用户定义的平方根函数 sqrt 单位制 http blogs msdn com andrewkennedy archive 2008 09 04 units of measure in f par
  • 正确使用术语 Monoid

    从下面的例子来看 我认为这样的说法是正确的String在串联运算下定义了一个幺半群 因为它是关联二元运算 并且String碰巧有一个身份元素 它是一个空字符串 scala gt Jane Doe Jane Doe res0 Boolean
  • 为什么 Javascript 函数在实例化时的行为与执行时的行为不同?

    我来自 C PHP 并试图了解 Javascript 的想法 即函数是变量 对象并且具有准构造函数等 任何人都可以解释为什么以下代码会起作用 即 为什么实例化变量 函数时不显示 2 test 为什么执行变量 函数时不显示 1 test co
  • 为什么Racket中foldl的定义方式很奇怪?

    在 Haskell 中 与许多其他函数式语言一样 函数foldl被定义为 例如 foldl 0 1 2 3 4 10 这没关系 因为foldl 0 1 2 3 4 根据定义 0 1 2 3 4 但是 在 球拍 中 foldl 0 1 2 3

随机推荐

  • 使用 Scala Slick 实现高阶函数,实现 DRY 优点

    我知道我的 Scala Slick 数据访问层应该是什么样子 但我不确定这是否真的可能 假设我有一个 User 表 其中包含 id 电子邮件 密码等常用字段 object Users extends Table String String
  • Sailsjs/waterline 指定模型中的小数位数

    我如何告诉我的帆模型我想要一些特定的小数位type float 属性 喜欢decimalPlaces 4或者类似的东西 问题是 当我向此条目发布值时 磁盘上的值会被截断为 00 数百 个地方 说我想要 3243 2352362按原样存储 目
  • ENOENT:没有这样的文件或目录。?

    这是发布数据和文件时出现的错误 我遵循 academind 教程来构建 Restful API 服务 我也一直在寻找此类错误的答案 但对我来说没有任何作用 我使用 multer 上传文件 文件夹 上传 在文件夹中可用 但显示 ENOENT
  • Tomcat context.xml 中的资源名称属性如何工作?

    我们正在使用 JNDI 来查找我们的数据库连接 在Tomcat的全局context xml文件中 我们有类似以下内容
  • 什么是 0x43 MIDI 事件?

    我正在尝试编写一个 MIDI 解析器 但我遇到了官方文档中未记录的 MIDI 事件 即http www midi org techspecs midimessages php http www midi org techspecs midi
  • PostgreSQL:间隔“10 天”和当前行之间的范围

    我有一张表 用于存储每件商品的每日价格 如果价格尚未更新 则当天没有该商品的记录 我需要编写一个查询 为每个商品检索最新价格 并具有从当前行日期起 10 天的回溯窗口 否则返回NULL 我想用一个来实现这一点RANGE BETWEEN IN
  • 在 REST Assured 中,如何设置超时?

    我正在使用 RestAssured 2 8 0 我正在尝试设置自己的超时 用于网关超时 因此 如果我在 X 毫秒后没有得到响应 我想中止 I tried public static ValidatableResponse postWithC
  • 使用另一种类型过滤一种类型的键

    我正在尝试创建一种类型 如果它们不出现在另一种类型中 则该类型将递归地排除一种类型中的键 例如 给定两种类型 type TargetType a true b c true d true type InputType a string b
  • Cordova 无法添加 Android 失败,退出代码为 ENOENT

    I am trying to create an Android project with Cordova however i am getting an ENOENT error although i followed the tutor
  • 如何让 emacs 正确显示多字节编码文件?是骡子吗?

    当我打开多字节文件时 我得到 短期内 您可以使用备用编码系统重新访问该文件revert buffer with coding system 然后选择utf 16le 从中期来看 您可以在加载时提高 utf 16le 编码的优先级prefer
  • 获取全文搜索配置语言的完整列表

    to tsvector 支持多种语言 英语 德语 法语 如何获得这些语言的完整列表 有手册中的说明 https www postgresql org docs current textsearch psql html如何使用 psql 检索
  • 在发送给用户之前重命名文件?

    这可能是一个非常简单和愚蠢的问题 但我不知道我会如何去做 我正在用 PHP 为客户端站点构建一些文件托管功能 我在一个目录中有一个中央文件存储库 这是因为如果多人上传同一文件 客户端希望维护每个文件的一份副本 基于文件的 哈希 文件在转储到
  • 使用 SSE 内在函数时如何确保 NaN 传播?

    我最近读到了这篇关于NaNSSE 算术运算中的值 对两个非数字 NAN 参数进行算术运算的结果是未定义的 因此 使用 NAN 参数的浮点运算将与相应汇编指令的预期行为不匹配 Source http msdn microsoft com en
  • 如何在 Spring Data REST 中添加根资源的链接?

    如何在中公开外部资源 不通过存储库管理 资源的根列表Spring Data REST 的 我按照以下模式定义了一个控制器休息金 https github com olivergierke spring restbucks blob mast
  • Chunky 界面含义

    在我正在阅读的 应用程序架构设计 一书中 我发现了以下说法 为了减少往返并提高 通讯性能 设计 厚实的接口 谁能解释一下 厚重的界面 是什么意思 基本上 它是指一次调用中传输的数据量 例如 如果您想从服务器获取一组数据 而不是询问 GetR
  • Geckoview 获取麦克风权限

    我正在尝试使用 GeckoView 元素内网站的录音功能 因此我在 AndroidManifest xml 中设置了权限
  • 闲置/不活动 60 秒后重定向用户?

    如何在我的网站上使用 JavaScript 将用户重定向到 logout60 秒不活动后页面 我知道设置计时器或使用元刷新标记很简单 但我只想重定向不活动的用户 而不是中断某人的活动会话 使用 这可以用 JavaScript 实现吗 您所需
  • 升级到 Babel 7:无法读取 null 的属性“绑定”

    我刚刚升级到Babel 7 https babeljs io docs en index html 从 6 开始 运行以下命令 npm remove babel cli npm install save dev babel cli babe
  • 对象 scalatest 不是包 org 的成员

    我想在 scalatest 中为我的玩具项目编写一些测试 当我使用sbt我通过安装了scalatestlibraryDependencies org scalatest scalatest 2 0 M5 test 在我的项目根目录中buil
  • “foldp”是否违反了 FP 的不可变状态原则?

    我正在学习 Elm七周内增加七种语言 http pragprog com book 7lang seven more languages in seven weeks 下面的例子让我很困惑 import Keyboard main lift