首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Haskell rec关键字是如何工作的?

Haskell rec关键字是如何工作的?
EN

Stack Overflow用户
提问于 2011-03-23 21:21:44
回答 2查看 4.5K关注 0票数 26

在arrow do notation中,您可以使用rec关键字编写递归定义。举个例子:

代码语言:javascript
运行
复制
rec
    name <- function -< input
    input <- otherFunction -< name

这怎么能进行评估呢?它看起来就像是进入了一个无限循环或者别的什么。我知道它的计算结果是循环箭头组合器,但我也不明白它是如何工作的。

编辑: powers示例非常有用。但是,如何使用do表示法来编写呢?我假设你需要使用rec。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-23 21:33:10

这点魔法是由于haskells的懒惰而起作用的。正如您可能知道的,Haskell在需要时而不是在定义时计算值。因此,如果您不需要直接或稍后输入该值,则可以使用此方法。

rec是使用ArrowLooploop函数实现的。它的定义如下:

代码语言:javascript
运行
复制
class Arrow a => ArrowLoop a where
        loop :: a (b,d) (c,d) -> a b c

instance ArrowLoop (->) where
        loop f b = let (c,d) = f (b,d) in c

您可以看到:输出只是作为输入进行反馈。它只会被计算一次,因为Haskell只会在需要的时候评估d

下面是一个如何直接使用loop组合器的实际示例。此函数计算其参数的所有幂:

代码语言:javascript
运行
复制
powers = loop $ \(x,l) -> (l,x:map(*x)l)

(你也可以这样写:powers x = fix $ (x :) . map (*x))

它是如何工作的?好的,无限的权力列表在l的论点中。评估结果如下所示:

代码语言:javascript
运行
复制
powers = loop $ \(x,l) -> (l,x:map(*x)l) ==>
powers b = let (c,d) = (\(x,l) -> (l,x:map(*x)l)) (b,d) in c ==>
powers b = let (c,d) = (d,b:map(*b)d) in d ==> -- Now  we apply 2 as an argument
powers 2 = let (c,d) = (d,2:map(*2)d) in d ==>
         = let (c,(2:d)) = (d,2:map(*2)d) in c ==>
         = let (c,(2:4:d)) = ((2:d),2:map(*2)(2:d)) in c ==>
         = let (c,(2:4:8:d)) = ((2:4:d),2:map(*2)(2:4:d)) in  ==> -- and so on
票数 27
EN

Stack Overflow用户

发布于 2011-03-24 04:46:12

下面是一个真实的例子:

代码语言:javascript
运行
复制
loop f b = let (c,d) = f (b,d) in c

f (b,d) = (drop (d-2) b, length b)

main = print (loop f "Hello World")

这个程序输出"ld“。函数'loop f‘接受一个输入'b’,并创建一个输出'c‘。'f‘正在做的是研究'b’来产生'length b‘,它被返回到循环并绑定到'd’。

在‘循环’中,这个'd=length b‘被输入到'f’中,在丢弃的计算中使用它。

这对于构建不可变的双向链表(也可以是循环的)这样的技巧很有用。它对于遍历一次'b‘也很有用,既可以产生一些解析的'd’(例如长度或最大元素),也可以构建一个依赖于'd‘的新结构'c’。懒惰避免了必须遍历“b”两次。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5405850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档