take 2 $ [1..] 在 haskell 中如何工作?

2024-03-17

我们知道 $ 运算符绑定的是最松散的,并且也关联到右侧,这意味着 [1..] 应该首先被评估,因此,它不应该陷入无限循环吗?为什么它甚至完全停止了?


Haskell is lazy, and ($) doesn’t change that. The ($) operator isn’t at all magical, and it’s a totally ordinary Haskell function:

($) :: (a -> b) -> a -> b
f $ x = f x

由于 Haskell 是惰性的,参数在传递给函数之前不会被求值,并且($)也不例外。所以,take 2 $ [1..](take 2) [1..],这当然等同于take 2 [1..]。不进行额外的评估。

现在,事实证明,有is的严格版本($) called ($!) https://hackage.haskell.org/package/base-4.10.0.0/docs/Prelude.html#v:-36--33-,它将其参数评估为弱头正常型 (WHNF) https://stackoverflow.com/a/6889335/465378在应用该功能之前。也可以定义为普通的Haskell函数,但必须使用神奇的seq函数作为其定义的一部分:

($!) :: (a -> b) -> a -> b
f $! x = x `seq` f x

然而,即使take 2 $! [1..]将产生[1,2],不发散。为什么?出色地,$!只将其参数评估为 WHNF,not正常形式,WHNF 可以被认为是“浅层”评估。它评估第一对缺点,但仅此而已。您可以使用以下命令看到这一点:sprintGHCi 中的命令:

ghci> let xs = [1..] :: [Int]
ghci> xs `seq` ()
()
ghci> :sprint xs
xs = 1 : _

要递归强制一个值,您需要使用the deepseq package https://hackage.haskell.org/package/deepseq,顾名思义,深度评估一个值。它提供了一个甚至“更强”的版本($),称为($!!) https://hackage.haskell.org/package/deepseq-1.4.3.0/docs/Control-DeepSeq.html#v:-36--33--33-,就像($!)但使用deepseq https://hackage.haskell.org/package/deepseq-1.4.3.0/docs/Control-DeepSeq.html#v:deepseq代替seq。所以,take 2 $!! [1..] will,其实是有分歧的。


† This is not strictly true in GHC, since there are some special typing rules in the compiler to help check idiomatic uses of $ when used with higher-rank types https://stackoverflow.com/a/9469942/465378. However, none of that is at all relevant here, and the simpler definition works identically.

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

take 2 $ [1..] 在 haskell 中如何工作? 的相关文章

  • 通过 Emacs 评估 ghci 或 Hugs 中的缓冲区

    在 Emacs 中使用 sml mode 我已经能够使用以下命令将缓冲区内容直接发送到较差的 SML 进程C c C b 现在我只想用 Haskell 做同样的事情 Haskell 模式似乎不支持这一点 所以我想知道 使用 Emacs 和
  • 如何在 Yesod 中使用 CSS 框架?

    我想将 Blueprint CSS 框架与 Yesod 一起使用 有没有最佳实践 因为 Yesod 使用 CSS 模板 所以在我看来我不能直接使用 css 文件 我必须将它们重命名为 lucius files 吗 如何将 CSS 添加到 d
  • 生成所有可能的树

    给定以下数据类型定义 data FormTree Empty Node FormTree FormTree deriving Show 我想编写一个函数 它生成一个无限列表 其中包含按长度排序的所有可能的树 例如节点数量 下面的代码几乎满足
  • Haskell:找不到模块“Data.List.Split”

    我正在尝试在 Haskell 中拆分列表 据我所知 最简单的方法是splitOn 但是这个函数需要Data List Split 所以我尝试运行import Data List Split在前奏曲中 但是 我收到以下错误 Could not
  • 为什么 Haskell 中有协函子和逆变函子的区别,而范畴论却没有区别?

    这个答案是从范畴论的角度来看的 https math stackexchange com a 661989 72174包括以下语句 事实是 协函子和逆变函子之间没有真正的区别 因为每个函子只是一个协变函子 More in details a
  • 如何为强制长度为 2^n 的向量类型定义可用的 Applicative 实例

    对于某些应用程序 我需要长度为 2 n 的向量 为了强制某些操作的长度匹配 我使用 ist 应用实例定义了我的类型 如下所示 LANGUAGE GADTs DataKinds FlexibleInstances FlexibleContex
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • Haskell 类型系统的细微差别

    我一直在深入了解 haskell 类型系统的本质 并试图了解类型类的要点 我已经学到了很多东西 但我在下面的代码片段上遇到了困难 使用这些类和实例定义 class Show a gt C a where f Int gt a instanc
  • 如何手动推断表达式的类型

    给定 Haskell 函数 head filter fst 现在的问题是如何手动 手动 找到类型 如果我让 Haskell 告诉我我得到的类型 head filter fst Bool b gt Bool b 但我想了解仅使用所用函数的签名
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon
  • Haskell 泛化问题(涉及列表理解)

    假设我想知道a上的所有要点 x y 矩形内的平面has 我可以使用列表推导式来计算 如下所示 let myFun2D x y x lt 0 2 y lt 0 2 现在 如果我想为一个人完成同样的事情 x y z 空间 我可以采取同样的方式并
  • 如何在 Haskell 中漂亮地打印表格?

    我想在 Haskell 中漂亮地打印一个类似表格的数据结构 列列表 例如 Table StrCol strings a bc c IntCol ints 1 30 2 DblCol doubles 2 0 4 5 3 2 应该渲染类似 st
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • Haskell:Data.Numbers.Primes 库在哪里?

    我尝试导入 Data Numbers Primes import Data Numbers Primes 伦哈斯克尔给了我 5 hs 1 8 Could not find module Data Numbers Primes Use v t
  • 用于遇到 [...] 的 Haskell Parsec 解析器

    我正在尝试使用 Parsec 在 Haskell 中编写一个解析器 目前我有一个可以解析的程序 test x 1 2 3 end 执行此操作的代码如下 testParser do reserved test v lt identifier
  • 带有 RankNTypes 扩展的奇怪类型推断

    我正在尝试在 Haskell 中尝试 System F 类型 并通过以下方式实现了自然数的 Church 编码type 当加载这段代码时 OPTIONS GHC Wall LANGUAGE RankNTypes type CNat fora
  • 如何打乱列表?

    如何从一组数字 1 2 3 直到我击中x 我的计划是重新调整列表 1 2 3 并把它砍在x chopAt 3 2 3 1 2 3 chopAt 3 2 1 3 2 1 3 chopAt 3 3 1 2 3 chopAt chopAt x y
  • 类型级别集结合律的证明

    我试图证明类型级函数Union https hackage haskell org package type level sets 0 8 5 0 docs Data Type Set html t Union是关联的 但我不确定应该如何完
  • C++ 概念与 Haskell 类型类有何不同?

    Concepts TS 中的 C 概念最近已合并到 GCC 主干中 概念允许人们通过要求类型满足概念的条件 例如 可比较 来约束通用代码 Haskell 有类型类 我对 Haskell 不太熟悉 概念和类型类如何相关 概念 由概念 TS 定

随机推荐