我正在学习Haskell,并且遇到了以下代码:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)
就其工作方式而言,我在解析方面遇到了一些麻烦.它非常整洁,我知道不需要更多内容,但我想了解Haskell在写作时如何设法"填写"文件:
take 50 fibs
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
谢谢!
我很难理解Clojure rest和nextClojure 之间的区别.官方网站关于懒惰的页面表明偏好可能应该是使用rest,但它并没有真正解释两者之间的差异.任何人都能提供一些见解吗?
我经常读到懒惰与非严格不一样,但我发现很难理解其中的区别.它们似乎可以互换使用,但我知道它们有不同的含义.我会很感激帮助理解差异.
关于这篇文章,我有几个问题.我将在本文末尾总结这些问题.我有几个示例片段,我没有测试它们,我只是将它们作为概念呈现.我添加了引号以避免查找它们.也许它会在以后有同样的问题帮助某人.
如果函数f应用于非终止表达式时,它也无法终止,则称函数f是严格的.换句话说,如果f bot的值为|,则f是严格的 .对于大多数编程语言,所有功能都是严格的.但在Haskell中并非如此.作为一个简单的例子,考虑const1,常量1函数,定义如下:
const1 x = 1
Haskell中const1 bot的值是1.从操作上讲,由于const1不"需要"其参数的值,因此它永远不会尝试对其进行求值,因此永远不会陷入非终止计算中.出于这个原因,非严格函数也被称为"惰性函数",据说可以"懒惰地"或"按需"来评估它们的参数.
我真的很喜欢这个定义.这似乎是我能找到的最好的理解严格的.是const1 x = 1懒惰的呢?
非严格意味着减少(评估的数学术语)从外部进行,
所以如果你有(a +(b c))那么首先减少+,然后你减少内部(b c).
Haskell Wiki真让我困惑.我理解他们对订单的看法,但是我没有看到(a+(b*c))如果通过它会如何非严格地评估_|_?
在非严格评估中,除非它们实际用于评估函数体,否则不评估函数的参数.
在教会编码下,运营商的懒惰评估映射到非严格的功能评估; 因此,非严格评估通常被称为"懒惰".许多语言中的布尔表达式使用一种称为短路评估的非严格评估形式,一旦可以确定将产生明确的布尔值,评估就会返回 - 例如,在遇到true的析取表达式中,或者遇到false的连接表达式,等等.条件表达式通常也使用惰性求值,一旦明确的分支将导致评估返回.
另一方面,懒惰评估意味着仅在需要其结果时评估表达式(注意从"缩减"到"评估"的转变).因此,当评估引擎看到一个表达式时,它会构建一个thunk数据结构,其中包含评估表达式所需的任何值,以及指向表达式本身的指针.当实际需要结果时,评估引擎调用表达式,然后将thunk替换为结果以供将来参考....
显然,thunk和部分评估表达式之间存在强烈的对应关系.因此,在大多数情况下,术语"懒惰"和"非严格"是同义词.但并不完全.
这似乎是Haskell的具体答案.我认为懒惰意味着thunks和非严格意味着部分评估.那个比较太简单了吗?难道懒总是意味着的thunk和非严格总是意味着部分评价.
在编程语言理论中,惰性评估或按需调用1是一种评估策略,它延迟表达式的评估,直到其值实际需要(非严格评估)并且还避免重复评估(共享).
我知道大多数人在学习函数式语言时会忘记命令式编程.但是,我想知道这些是否属于非严格,懒惰,两者兼而有之?至少它会提供熟悉的东西.
短路
f1() || f2()
Run Code Online (Sandbox Code Playgroud)
C#,Python和其他语言"产量"
public static …Run Code Online (Sandbox Code Playgroud) 我是否理解这一点
def 每次访问时都会进行评估
lazy val 一旦被访问就被评估
val 进入执行范围后进行评估?
例如,如果我有以下声明:
if( foo1 or foo2)
...
...
Run Code Online (Sandbox Code Playgroud)
如果foo1为true,python会检查foo2的条件吗?
我正在阅读Hadley Wickhams关于Github的书,特别是关于懒惰评估的这一部分.在那里,他举例说明了懒惰评估的后果,在有add/adders功能的部分.让我引用一下:
在使用lapply或循环创建闭包时,[懒惰评估]很重要:
Run Code Online (Sandbox Code Playgroud)add <- function(x) { function(y) x + y } adders <- lapply(1:10, add) adders[[1]](10) adders[[10]](10)在第一次调用其中一个加法器函数时,会对x进行延迟计算.此时,循环完成,x的最终值为10.因此,所有加法器函数都会在其输入上添加10,可能不是您想要的!手动强制评估修复了问题:
Run Code Online (Sandbox Code Playgroud)add <- function(x) { force(x) function(y) x + y } adders2 <- lapply(1:10, add) adders2[[1]](10) adders2[[10]](10)
我似乎不明白那一点,而且那里的解释很少.有人可以详细说明这个特定的例子,并解释那里发生了什么?我特别对句子感到困惑"此时,循环完成,x的最终值为10".什么循环?什么最终价值,在哪里?一定是简单的我想念,但我只是没有看到它.非常感谢提前.
C++没有对延迟评估的本机支持(如Haskell所做的那样).
我想知道是否有可能以合理的方式在C++中实现延迟评估.如果是的话,你会怎么做?
编辑:我喜欢Konrad Rudolph的回答.
我想知道是否可以以更通用的方式实现它,例如通过使用参数化类lazy,它基本上适用于矩阵矩阵的矩阵.
对T的任何操作都会返回惰性.唯一的问题是将参数和操作代码存储在惰性本身中.任何人都可以看到如何改善这一点?
Haskell有一个神奇的函数命名seq,它接受任何类型的参数并将其简化为弱头范式(WHNF).
我读过几个消息来源[不是我记得他们现在是谁...],声称"多态seq是坏的".他们以什么方式"坏"?
类似地,有一个rnf函数,它减少了Normal Form(NF)的参数.但是,这是一个类的方法; 它不适用于任意类型.对我来说似乎"显而易见",人们可以改变语言规范,将其作为内置原语提供,类似于seq.据推测,这可能比仅仅更糟糕seq.这是怎么回事?
最后,有人建议给seq,rnf,par和同类者同类型的id功能,而不是const功能,因为它是现在,会是一个进步.怎么会这样?
在命名空间中MS.Internal,有一个名为的类NamedObject.
它有一个奇怪的代码块:
public override string ToString()
{
if (_name[0] != '{')
{
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
}
return _name;
}
Run Code Online (Sandbox Code Playgroud)
我特别好奇这个评论:
// lazily add {} around the name, to avoid allocating a string
// until it's actually needed
_name = String.Format(CultureInfo.InvariantCulture, "{{{0}}}", _name);
Run Code Online (Sandbox Code Playgroud)
那个'懒惰'怎么样?懒惰是做什么用的?
从满级的参考来源:
//----------------------------------------------------------------------------
//
// <copyright file="NamedObject.cs" company="Microsoft">
// Copyright (C) Microsoft Corporation. …Run Code Online (Sandbox Code Playgroud) 我想使用下面的计算参数化dplyr,找出哪些值Sepal.Length与多个值相关联Sepal.Width:
library(dplyr)
iris %>%
group_by(Sepal.Length) %>%
summarise(n.uniq=n_distinct(Sepal.Width)) %>%
filter(n.uniq > 1)
Run Code Online (Sandbox Code Playgroud)
通常我会写这样的东西:
not.uniq.per.group <- function(data, group.var, uniq.var) {
iris %>%
group_by(group.var) %>%
summarise(n.uniq=n_distinct(uniq.var)) %>%
filter(n.uniq > 1)
}
Run Code Online (Sandbox Code Playgroud)
但是,这种方法会因为dplyr使用非标准评估而引发错误.应该如何编写这个函数?
lazy-evaluation ×10
haskell ×3
r ×2
c# ×1
c++ ×1
clojure ×1
definition ×1
dplyr ×1
fibonacci ×1
list ×1
properties ×1
python ×1
scala ×1