- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在从 Hutton 的书《Programming in Haskell》(第二版)中学习 Haskell。在第 1 章的开头。 7、《高阶函数》,函数'twice'定义为:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
然后给出一些使用示例,例如:
> twice reverse [1,2,3]
[1,2,3]
然后作者说,“将(有限)列表反转两次没有效果的事实可以通过等式两次反转= id来捕获......”当我启动 ghci 并写入时:
GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help
Prelude> :type twice
<interactive>:1:1: error: Variable not in scope: twice
Prelude> twice reverse = id
Prelude> :type twice
twice :: p -> a -> a
Prelude> twice reverse [1,2,3]
[1,2,3]
这实际上是一个函数定义,因为两次之前没有定义。现在,我的问题是它是如何运作的? 两次反向是否只是定义为id的别名?但如果是这样,为什么我可以单独查询两次的类型? Haskell语言报告中有哪些相关部分用于解释这种函数定义语法?另外,为什么使用类型变量p?通常使用a、b等。
编辑
感谢到目前为止提供的有用回答和评论!
我只是想提供一些关于我提出的尚未得到解决的其他问题的更多背景信息。当然,最重要的问题已经得到解答。
为什么其中一个类型变量名为 p?
让我们看一下下面的 ghci session :
GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help
Prelude> twice asdf fsda = id
Prelude> :type twice
twice :: p1 -> p2 -> a -> a
Prelude> mySum a b c d = a + c
Prelude> :type mySum
mySum :: Num a => a -> p1 -> a -> p2 -> a
似乎p或p1、p2等被用作未使用的变量的泛型类型。也许它们还用于其他目的。我在 article 中找到了提示在另一个问答论坛上。用于泛型类型变量的名称甚至可能是特定于实现的。重要的信息是,使用哪些字母并不重要,重要的是它们不同。
语言规范的相关部分是什么?
可能是第 1 章。 4.4.3,“函数和模式绑定(bind)”,2010 年 Haskell 语言报告。但现在这对我来说信息太多了。毕竟我正在阅读一本介绍性 Haskell 书的前半部分。
最佳答案
让我们逐步了解一下您在这里所做的事情。首先,您定义:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
这是一个正常的函数定义,并且按照您的预期工作:两次 (+1) 2 = 3
、两次反转 "abc"= "abc"
等。当 Hutton 说“方程两次反向= id
捕获了两次(有限)列表反转没有效果的事实”时,他只是说两次反向
与执行 id
具有相同的效果。
但是然后,你定义:
twice reverse = id
这并没有达到您的预期!您可能希望这可以验证等式“两次反向 = id”或类似的内容是否成立。相反,它定义了一个全新的函数 twice
,将其唯一参数命名为 reverse
,然后忽略该参数并返回 id
函数。在这里,您正在使用遮蔽:您正在定义一个与旧标识符同名的新标识符(在本例中为反向
)。事实上,如果您使用 -Wall
启用所有警告,GHC 会警告您:
Prelude> :set -Wall
Prelude> twice reverse = id
<interactive>:2:7: warning: [-Wname-shadowing]
This binding for `reverse' shadows the existing binding
imported from `Prelude' (and originally defined in `GHC.List')
因此,定义两次reverse = id
与定义一个函数两次myArg = id
没有什么不同,只是参数具有不同的名称。
关于haskell - Haskell 中具有 LHS 和 RHS 函数的函数定义如何/为什么起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62492875/
我知道 a = val1 if condition else val2 但是有没有办法做类似的事情 a if condition else b = val 抛出一个SyntaxError(我想这是可以
我遇到了一些归结为以下内容的代码: enum BAR { /* enum values omitted */ } class Foo{ public: void set(const BAR& ba
我是 R 新手,我想用 *apply 改进以下脚本函数(我已经阅读了 apply ,但我无法使用它)。我想用lm在多个自变量(数据框中的列)上运行。我用了 for (i in (1:3) { as
我知道要问这种有趣的问题。我想知道这是否可以做到? Class foo { public static void main(String [] args){ for (int i=0; i = new
分配给表达式(而不是名称)在 Python 中很常见。例如,这是完全有效的语法: my.object["with_some"].very_long["expression"] = func(my.ob
我想在 R 中的一行中分配多个变量。可以这样做吗? values # initialize some vector of values (a, b) = values[c(2,4)] # assign
以下程序的输出未给出预期结果: #include int main() { int *x; int *y; *x = 10; *y = 45; printf
我正在学习流口水并试图了解最佳实践。之间有什么实际区别: when $event : Event(Helper.notNull(foo),...) 和 when $event : Ev
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 7 年前。 Improve
给出以下类: template class table2D { ... public: bool copy(int r, int c, int rows , int cols, ta
我知道以下关于引用 例如。 int &ref=x;然后 ref 和 x 是内存中相同位置的名称。与指针不同,内存不是为引用分配的。 我正在使用我成功编写的引用在 C++ 中编写一个简单的交换程序。 然
尝试在 Python + Gurobi 中实现指标约束,其中指标(LHS)是二元决策变量的总和。 嗨,我想在 Python + Gurobi 中实现以下功能: Y_i_d and U_d are bi
假设我有这样的代码: #include "boost/thread/mutex.hpp" using boost::mutex; typedef mutex::scoped_lock lock; mu
这个问题在这里已经有了答案: In f(x), can x be evaluated before f? (2 个答案) 关闭 5 年前。 我已阅读 Order of evalution来自cppr
我正在学习 C++ 异常,我想对场景进行一些说明: T function() throw(std::exception); ... T t = value; try { t = function();
有谁知道 Mathematica 中是否有一个内置函数来获取降值规则的 lhs(没有任何持有)?我知道如何编写代码来做到这一点,但对于内置的 例如: a[1]=2; a[2]=3; BuiltInID
我碰巧真的很喜欢 Markdown(可能是因为 SO)而且我喜欢用 Haskell 编程。我最近发现了Literate Haskell (LHS) 我想同时使用 Markdown 和 LHS。让我给你
我想从 arules 生成的规则中提取 lhs 项。 例如, {a,b,c} => {d} 我希望能够提取 a,b,c 并将其放入字符向量中,以便我可以根据这些项目进行迭代和进一步处理。 目前,我可以
sap.ui.core.Control.extend("control.linechart", { /* the control API */ metadata : {
我正在尝试编写一个使用迭代深化算法来解决规划问题的 CLIPS 程序。出于同样的原因,我想保持较低的分支因子。 在以下代码中?s是表示树的级别的变量;我想使用一个规则来进行不同的检查。这就是我试图做的
我是一名优秀的程序员,十分优秀!