【问题标题】:Yin-yang puzzle in RubyRuby 中的阴阳谜题
【发布时间】:2021-10-09 09:36:36
【问题描述】:

为了进一步了解call/cc,我看到How does the yin-yang puzzle work?问题和this explaination关于阴阳谜题:

(let*
    (
        (yin (
            (lambda (cc) (display #\@) cc)
            (call/cc (lambda (c) c))
        ))
        (yang (
            (lambda (cc) (display #\*) cc)
            (call/cc (lambda (c) c))
        ))
    )
    (yin yang)
)

到目前为止,我可能(或可能不)理解阴阳谜题的概念。但是我发现scheme语法不是特别好理解,一搜发现ruby有Continuation模块。由于 ruby​​ 语法遵循过程式风格,我发现 ruby​​ 代码比方案代码更容易阅读。因此我决定将这个谜题翻译成 ruby​​ 版本(我既是 scheme 又是 ruby​​ 新手):

require "continuation"

yin = (lambda do |cc|
    print "@"
    return cc
end).call(callcc {|c| c})

yang = (lambda do |cc|
    print "*"
    return cc
end).call(callcc {|c| c})

yin.call(yang)

但是这个版本打印出@*@***********... (demo here) 而不是@*@**@***@****@*****@**...,这不是我所期望的。

我的 ruby​​ 版本是否正确?如果它不正确,那么我真的不知道从这里该怎么做......

【问题讨论】:

  • "...我发现阅读 ruby​​ 代码比阅读方案代码容易得多。" -- 好吧,当它被格式化时阅读 lisp 代码要困难得多以花括号语言的方式。不要将括号分散在不同的行上;研究以惯用方式编写的 lisp 代码的格式,并模仿它。一旦你习惯了 lisp 的典型格式化方式,它就会像任何其他代码一样容易和自然地阅读。

标签: ruby scheme continuations


【解决方案1】:

我认为yinyang 将成为Continuation 的问题,它们不会一起调用,而只有yang 嵌套在yin 中。

yin = (lambda do |cc|
  print "@"
  return cc # (3) return Continuation (1)
end).call(callcc {|c| c}) # (1) this params call first

# (2) lambda will call immediately -> print the first @
# so yin = Continuation (1)

yang = (lambda do |cc|
  print "*"
  return cc # (6) return Continuation (4)
end).call(callcc {|c| c}) # (4) this params call first *

# (5) lambda will call immediately -> print the first *
# so yang = Continuation (4)

yin.call(yang)

现在我们可以将您的代码解释如下

yin = callcc {|c| c} # yin context
  print '@'
  yang = callcc {|cc| cc} # yang context
    print '*'
    yin.call(yang)
  # end yang context
# end yin context

如你所见,在第一次调用(第二个@和*)后,最后一行yin.call(yang)将保持调用yangyang ( * yang ( * yang ( ...,如果你替换为yin.call(yin),输出将是@*@*@*@*...

最后,这是我的解决方案,想法是yinyang 将嵌套在一起,下一个yang 将包含上一个yin + '*',下一个yin 将包含上一个yang + '@'

require "continuation"

yin = lambda { |yang|
  cc = callcc { |cc| cc }
  print "@"
  yang.call(cc)
}
  
yang = lambda { |yin|
  cc = callcc { |cc| cc }
  print "*"
  yin.call(cc)
}

yin.call(yang)

【讨论】:

    猜你喜欢
    • 2013-11-26
    • 2012-03-04
    • 1970-01-01
    • 2015-08-05
    • 2017-06-08
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    相关资源
    最近更新 更多