- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一种我自己设计的函数式编程语言,我偶然发现了一个超出我解决能力的问题。我想知道是否有人对如何解决它有任何建议,或者为什么它是不可能的。
下面的代码概述了一个不是理想但妥协的解决方案。
这个问题是我目前使用的运行时系统的核心。我没有依赖 .Net 堆栈,而是使用 monad 在蹦床上执行操作。这应该有助于逐步调试,并使用户不必担心堆栈空间。这是我目前使用的 monad 的简化版本。
type 't StackFree =
|Return of 't //Return a value
|StackPush of ('t->'t StackFree)*'t StackFree //Pushes a return handler onto the "Stack"
|Continuation of (unit->'t StackFree) //Perform a simple opperation
type StackFreeMonad() =
member this.Delay(fn) =
Continuation(fn)
member this.Bind(expr,fn) =
StackPush(fn,expr)
member this.Return(value) =
Return(value)
member this.ReturnFrom(x) =x
let stackfree = StackFreeMonad()
type 't Running =
|Result of 't
|Step of (unit->'t Running)
//this method loops through the StackFree structure finding the next computation and managing a pseudo stack with a list.
let prepareStackFree<'t> :'t StackFree->'t Running =
let rec inner stack stackFree =
Step(fun ()->
match stackFree with
//takes the return values and passes it to the next function on the "Stack"
|Return(value)->
match stack with
|[]->Result(value)
|x::xs -> inner xs (x value)
//pushes a new value on the the "Stack"
|StackPush(ret,next) ->
inner (ret::stack) next
//performs a single step
|Continuation(fn)->
inner stack (fn()))
inner []
let run<'t> :'t StackFree->'t =
let rec inner = function
|Step(x)-> inner (x())
|Result(x)-> x
stackFreeToRunning>>inner
//silly function to recompute an intiger value using recursion
let rec recompute number = stackfree {
if number = 0 then return 0
else
let! next = recompute (number-1)
return next+1
}
let stackFreeValue = recompute 100000
let result = run stackFreeValue
do printfn "%i" result
type RunningMonad() =
member this.Delay(fn) =
Step(fun ()->fn ())
member this.Bind(m, fn) =
Step(fun ()->
match m with
|Result(value)-> fn value
//Here is the problem
|Step(next)-> this.Bind(next(),fn))
member this.Return(v) =
Result(v)
member this.ReturnFrom(x) = x
最佳答案
迟到总比不到好!
这在 Stackless Scala with Free Monads 的第 4 节中得到解决。 . Bjarnason 通过向 Trampoline
添加一个新的构造函数来解决这个问题。数据类型,表示对另一个蹦床的子例程调用。他将这个新的构造函数保持为私有(private),以确保您不能构建左嵌套 Bind
s(执行蹦床时会溢出堆栈)。
我绝不是 F#er,但我会应付自如。在我刚刚编造的一个虚构的 F# 方言 WishF#ul 中,您可以直接表达新的存在量化构造函数:
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call<'x> of Tram<'x> * ('x -> Tram<'a>) // don't export this
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) = match ma with
| Call(mx, k) -> Call(mx, fun x -> this.Bind(k(x), f))
| _ -> Call(ma, f)
// i confess to not quite understanding what your Delay and ReturnFrom methods are for
let tram = new TramMonad()
let rec runTram t =
let next mx f = match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(my, g) -> tram.Bind(my, fun x -> tram.Bind(g x, f))
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(mx, f) -> runTram(next mx f)
runTram
的递归调用处于尾部位置。这有点令人费解,但你可以说服自己
Bind
不会构建深度嵌套的延续,所以
runT
将始终在 O(1) 堆栈空间中运行。
Call
中存在类型的面向对象编码。构造函数。开始...
module rec Trampoline =
type Call<'a> =
abstract member Rebind<'b> : ('a -> Tram<'b>) -> Tram<'b>
abstract member Next : unit -> Tram<'a>
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call of Call<'a>
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) =
match ma with
| Call(aCall) -> aCall.Rebind(f)
| _ -> call ma f
let tram = new TramMonad()
let rec call<'a, 'x>(mx : Tram<'x>) (f : 'x -> Tram<'a>) : Tram<'a> = Call {
new Call<'a> with
member this.Rebind<'b>(g : 'a -> Tram<'b>) : Tram<'b> =
call<'b, 'x> mx (fun x -> tram.Bind(f x, g) : Tram<'b>)
member this.Next() =
match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(aCall) -> aCall.Rebind(f)
}
let rec runTram t =
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(aCall) -> runTram(aCall.Next())
Free (Unit -> _)
)。菲尔弗里曼的
Stack Safety for Free基于这项工作,将蹦床纸的免费单子(monad)推广到免费单子(monad)变压器。
关于f# - Stackless trampoline Monad/计算表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45152039/
根据这个答案 https://stackoverflow.com/questions/551950/what-stackless-programming-languages-are-available
我是编程新手,现在已经使用 Python 几个月了。我试图获得一个与 Stackless 一起工作的概念,但就是想不通如何(尽管我已经写了 other test scripts 与 Stackless
在Stackless Python in Eve , 在 Python 中有一些关于“蓝色”对象的讨论。有人知道这项技术的详细信息吗? 最佳答案 这是一个框架的代号CCP可能是为 EVE Online
我正在制作自己的类 Lisp 解释型语言,我想做尾调用优化。我想将我的解释器从 C 堆栈中解放出来,这样我就可以管理我自己的函数到函数的跳转以及我自己的堆栈魔术来实现 TCO。 (我真的不是指无堆栈本
是否可以在不使用节点堆栈或“已访问”标志的情况下对二叉树执行迭代 *预排序*遍历? 据我所知,此类方法通常要求树中的节点具有指向其父节点的指针。现在,可以肯定的是,我知道如何使用父指针 和 访问标志执
对于一些学术研究,我需要模拟在单个处理器上运行的多个线程。 我希望能够在我的代码中插入 *call_scheduler()* 调用,其中当前“线程”将暂停(记住它在哪一行代码中)并且一些调度函数将决定
所以我正在玩弄无堆栈 python,编写一个非常简单 的网络服务器来自学使用微线程/tasklet 进行编程。但现在我的问题是,当我在 apache bench 中运行类似 ab -n 100000
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在开发一种我自己设计的函数式编程语言,我偶然发现了一个超出我解决能力的问题。我想知道是否有人对如何解决它有任何建议,或者为什么它是不可能的。 下面的代码概述了一个不是理想但妥协的解决方案。 这个问
给定一个大型(4.5 GB 代码库)python 测试框架,其执行涉及数十个文件,其中许多文件不能直接 pickle,是否可以将程序的初始执行包装在一行函数中,创建一个围绕该函数的 Stackless
在对 Clang 中的协程 TS 的当前实现进行了一些尝试后,我偶然发现了 asio 无堆栈协程实现。它们被描述为 Portable Stackless Coroutines in One* Head
您在使用 Stackless Python 和 PyQt 方面有哪些经验? 如果人们解决我会很高兴的问题: PyQt for Stackless 编译:PyQt 是否需要专门为 Stackless 编
有很多与 Stackless Python 相关的问题。但是没有人回答我的问题,我想(如果错了请纠正我 - 请!)。一直有一些关于它的嗡嗡声,所以我很想知道。我会用 Stackless 做什么?它比
我从 Stackless Python 开始,所以它对我来说是一个全新的奇妙世界。我通常使用常规线程,它们通常具有线程本地存储 (TLS),这当您不需要与其他线程共享内存时,这是一个非常有用的功能。
以下代码改编自一篇论文(R. O. Bjarnason,Stackless Scala With Free Monads)。 论文的标题指出了所提出的数据结构的总体目的——即在恒定堆栈空间中提供递归处
有没有类似Stackless Python的东西,即在 C# 中支持延续、微线程和轻量级进程的框架?我知道 C# 5 将部分支持其中的一些功能。但是现在有什么可以用的吗? 最佳答案 Axum 类似,但
我知道标准 CPython 对递归深度有限制,我认为小于 1000,因此下面的示例代码将失败并出现“超出最大递归深度”错误。 def rec_add(x): if x == 0:
包含无堆栈的 PyPy 1.7 的默认构建不提供在没有递归深度限制的情况下运行的能力(以直接方式)。 为什么? Previus 构建的 PyPy 具有无堆栈支持函数调用和尾递归的延续风格。 我不是在问
我将 Roberto Ierusalimschy 的 Programming in Lua 中的示例翻译为使用 boost::asio 和 stackful coroutines 通过 HTTP 使用
我有一个典型的生产者、消费者模式。如果生产者通过 channel 发送对象,则生产者将被阻塞,直到消费者接受该对象。消费者接受对象后,生产者以某种方式改变对象。消费者是否看到对象被改变了?或者在通过
我是一名优秀的程序员,十分优秀!