- 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/
在 rxjava 中有一些调度器,就像 io(),newThread()...,有一个名为“trampoline”的调度程序,此调度程序用于:创建并返回一个调度程序,该调度程序将当前线程上的工作排队,
我正在尝试在 JavaScript 中实现基本的惰性序列。我只使用闭包和延续。这是我到目前为止得到的: var cons = curry(function(x, y, list){ return
我最近开始学习 JS,这是我第一次涉足函数式语言领域。 在 functional-javascript-workshop npm 模块中进行“蹦床”练习,发现我自己的解决方案与官方解决方案之间存在一个
我在谷歌上寻找这个,我发现了一些关于它的文章他们说它用于 HigherOrderMessaging,我试图阅读代码,但一切都在我的脑海中,任何人都可以给出简单的例子来说明我们如何使用他们?他们说它用于
我正在开发一种我自己设计的函数式编程语言,我偶然发现了一个超出我解决能力的问题。我想知道是否有人对如何解决它有任何建议,或者为什么它是不可能的。 下面的代码概述了一个不是理想但妥协的解决方案。 这个问
我们正在开发一个iOS应用。当我们在PC上测试该应用程序时,一切正常,但是当我们在iPad/iPhone4上运行该应用程序时,我们经常会收到“Ran out of Trampolines type 2
我用java编写了一个程序,它使用SQLite(v056)。 我使用语句(调用它的 executeQuery() 方法)多次查询数据库,并且效果很好。 一段时间后,它卡在了 trampoline()
我正在尝试计算从一条指令到另一条指令的相对地址偏移量。 我了解基本计算,以及为什么我必须 -5(以适应 jmp 的大小和指令大小)(Calculating JMP instruction's addr
我负责 F# WPF 应用程序 .当发生未处理的异常时,它会向我发送电子邮件。大多数情况下,我能够从错误消息和堆栈跟踪中确定异常的来源。但是,我偶尔会收到如下消息,其中不包含堆栈跟踪中的任何代码。 S
在我看来,lein run 和 lein Tampoline 之间的唯一区别是后者退出 Leiningen 的 JVM 以节省内存。 这似乎总是一个好主意,那么为什么这个功能不包含在lein run中
我想通过在遇到 StackOverflowError 时返回一个 thunk 来在 java 中实现一个蹦床。关于 StackOverflowError 是否有任何保证,例如,如果我在 StackOv
Trampoline是一个单子(monad),并为单子(monad)变压器堆栈增加了堆栈安全性。它通过依赖一个特殊的解释器( monadRec )来实现这一点,该解释器被输入单子(monad)计算的结
所以我一直在学习 Hook 和使用蹦床的概念,以便绕过/执行 WinAPI Hook 函数中的数据(在不同的可执行文件中,使用 DLL 注入(inject))。到目前为止,我知道如何使用汇编和 C 的
所以我一直在学习 Hook 和使用蹦床的概念,以便绕过/执行 WinAPI Hook 函数中的数据(在不同的可执行文件中,使用 DLL 注入(inject))。到目前为止,我知道如何使用汇编和 C 的
在 native 设备 (iPad) 上运行我的 MonoTouch 应用程序时,出现 SIGABRT/run out of trampolines 错误。 这在我的应用程序中很早就发生了 - 我正在
我在 https://github.com/ayoung/Newtonsoft.Json 尝试了 JSON.NET 和 MonoTouch 端口但是得到这个序列化错误: Ran out of tram
MonoTouch 6.0.8 release notes说: Runtime Trampolines: It is no longer necessary to manually manage tr
我正在寻找一种用于异步操作的数据类型。 我发现 scalaz.ContT[Trampoline, Unit, ?]支持 scalaz.concurrent.Future 中的所有功能,此外还有 Bin
我有 100 个左右的蹦床功能。我想知道是否可以自动将每个包装在 try/catch block 中。 请提前警告,这不是一个简单的问题。我将首先用(简化的)代码描述问题,然后在下面尝试尽可能地回答它
我是一名优秀的程序员,十分优秀!