我正在玩一种由monadic接口定义的DSL.
因为使用一堆flatMap应用程序应用monad是一种麻烦,我发现语法上的理解并不那么美,我试图使用分隔的continuation隐含地混合monadic和non monadic代码.
它实际上工作得很好,但我真的不满意这些类型,因为我必须将我的自我限制为"任意"类型才能编译:(.因此,当结果使用时,使用"Any"和"cast"需要可能导致运行时错误......
下面是一些示例代码,用于将Scala中的Option-Monad与常规代码混合,因此您可以看到我在说什么:
object BO {
import scala.util.continuations._
def runOption[C](ctx: => Any @cpsParam[Option[Any],Option[Any]]): Option[C] = {
val tmp : Option[Any] = reset {
val x : Any = ctx
Some(x)
}
tmp.asInstanceOf[Option[C]]
}
def get[A](value:Option[A]) = shift { k:(A=>Option[Any]) =>
value.flatMap(k)
}
class CPSOption[A](o:Option[A]) {
def value = get[A](o)
}
implicit def opt2cpsopt[A](o:Option[A]) = new CPSOption(o)
def test1 = runOption[Int] {
val x = get(None)
x
}
def test2 = runOption[Int] {
val x = Some(1).value
x
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Scala(2.9.0)延续来构建看似阻塞的API,但这实际上是异步的.假设你想写一些类似的东西:
if(ask("Continue?")) //Prompts Yes/No
name = input("Enter your name")
Run Code Online (Sandbox Code Playgroud)
当ask返回,当用户按下yes一个布尔,并input要求一个值.想象一下这是从Web服务器调用的,其中ask和input不阻塞任何线程,它们只是在显示带有提示的页面(释放大多数资源)之前在Map(或会话,无关紧要)中存储延续.当响应返回时,它会查找Map中的延续并恢复代码.
到目前为止的问题是,我似乎无法找到一种合适的方法来定义ask和input使用continuation而不将调用上下文的返回类型作为参数传递.
我得到的最接近的是:
#!/bin/sh
exec scala -P:continuations:enable -deprecation "$0" "$@"
!#
import util.continuations._
//Api code
def display[T](prompt: String) = shift {
cont: (Unit => T) => {
println(prompt)
cont()
}
}
//Client code
def foo() : Int = reset {
display[Int]("foo!") // <-- how do I get rid of the type annotation?
5
}
def bar() : Unit = …Run Code Online (Sandbox Code Playgroud) 我在一堆LINQ查询上有一些GUI.查询需要一些时间来执行,所以我希望GUI能够响应并显示busyindicators和进度条.许多查询都是检查数据中存在的某些条件.如果查询返回空结果,则应用程序将继续下一个查询.如果它返回结果,则返回集将具有严重性"警告"或"错误".如果是警告,则继续执行.如果是错误,它应该停止.
许多代码使用线程池和GUI播放"乒乓".准码:
TaskFactory.StartNew(()=>
{
Run in background
}.ContinueInGui(()=>
{
Update something
}).ContinueInBackground(()=>
{
Do more work;
}).ContinueInGui(()=> etc etc
Run Code Online (Sandbox Code Playgroud)
这很整洁.但是,如果在数据中发现错误,我不会看到如何插入条件来执行不同的延续路径或中断连续链.
ContinueWithIf没有方法(谓词,委托{},TaskScheduler)我是否使用TaskCancellation,是否抛出异常?或者是否有一些我没想到的简单分支机制?
我没有正式的延续知识,我想知道是否有人可以帮助我验证和理解我写的代码:).
我试图解决的一般问题是转换表达式
(2 * var) + (3 * var) == 4
Run Code Online (Sandbox Code Playgroud)
进入功能
\x y -> 2 * x + 3 * y == 4 -- (result)
Run Code Online (Sandbox Code Playgroud)
然后可以将其传递到yices-painless包中.
作为一个更简单的例子,请注意将var其翻译成\x -> x.我们怎样才能乘两个var的(表示他们\x -> x和\y -> y)到一个表达\x -> \y -> x * y?
我听说延续被描述为"计算的其余部分",并认为这就是我所需要的.遵循这个想法,var应该采取一种功能
f :: ? -> E -- rest of computation
Run Code Online (Sandbox Code Playgroud)
其参数将是创建的变量的值var,并返回我们想要的内容(代码列表标记result),一个新函数接受变量x并返回f x.因此,我们定义,
var' …Run Code Online (Sandbox Code Playgroud) 我试图实现一个返回递归闭包的函数.虽然我不知道如何在函数签名中表达它.这是Python中工作实现的示例代码
def counter(state):
def handler(msg):
if msg == 'inc':
print state
return counter(state + 1)
if msg == 'dec':
print state
return counter(state - 1)
return handler
c = counter(1)
for x in range(1000000):
c = c('inc')
Run Code Online (Sandbox Code Playgroud)
和Rust的伪代码.
enum Msg {
Inc,
Dec
}
fn counter(state: Int) -> ? {
move |msg| match msg {
Msg::Inc => counter(state + 1),
Msg::Dec => counter(state - 1),
}
}
Run Code Online (Sandbox Code Playgroud) 该ContT单子转换有一个有趣的属性:如果有一个* -> *类型,例如Set,已明确的单子操作,但不能有Monad实例由于一些限制(在这里Ord a),有可能把它包在ContT(ContT r Set)得到一个单子实例,并推迟约束外面,当我们像注入Set进ContT r Set.请参阅使用continuation monad 构造高效的monad实例Set.
箭头有类似的东西吗?一个箭头变换器,它允许将"几乎箭头"包装进去,得到一个有效的Arrow实例,并将有问题的约束推迟到我们向它注入"几乎箭头"的部分?
例如,如果我们有一个类型AlmostArrow :: * -> * -> *,我们有通常的Arrow操作,但有约束,如
arr' :: (Ord a, Ord b) => (a -> b) -> AlmostArrow a b
(>>>') :: (Ord a, Ord b, Ord c) => AlmostArrow a b -> AlmostArrow b c -> AlmostArrow a …Run Code Online (Sandbox Code Playgroud) continuations haskell arrows monad-transformers category-theory
回到那天,我虽然明白了call/cc。这些天我看到了更多对“分隔”延续运算符的引用,它们似乎成对出现,如shift/ reset、prompt/ control,有时还有更奇特的。但我还没有看到任何基础知识的明确解释,所以
scheme continuations haskell functional-programming delimited-continuations
假设,我想捕获异常,修复导致异常的问题并返回到发生异常的同一执行点继续.
如何在Scala中使用continuation实现它?它有意义吗?
我正在尝试Cont monad,并发现以下问题.
代码如下所示:
let inff = map (return :: a -> Cont r a) [0..]
let seqf = sequence inff
runCont seqf head
Run Code Online (Sandbox Code Playgroud)
那么这是Haskell中Cont monad实现的限制吗?如果是这样,我们如何改善这一点?
不使用 Continuations 进行编译描述了一种使用连接点扩展 ANF System F 的方法。GHC 本身在 Core(一种中间表示)中有连接点,而不是直接在表面语言(Haskell)中暴露连接点。出于好奇,我开始尝试编写一种语言,通过连接点简单地扩展 System F。也就是说,连接点是面向用户的。但是,我不明白论文中的打字规则。以下是我理解的部分:
?是?在几个规则。在表达式中let x:? = u in ...,u不能引用任何连接点(VBIND),因为它连接点不能返回到任意位置。JBIND。这篇论文很好地解释了这一点。这是我没有得到的。论文引入了一个符号,我将其称为“高架箭头”,但论文本身并没有明确给出名称或提及它。从视觉上看,它看起来像一个指向右侧的箭头,它位于表达式之上。粗略地说,这似乎表示“尾部上下文”(论文确实使用了这个术语)。在论文中,这些开销箭头可以应用于术语、类型、数据构造函数,甚至环境。它们也可以嵌套。这是我遇到的主要困难。有几条规则包含在头顶箭头下的类型环境。JUMP, CASE, RVBIND, 和RJBIND都包括具有这种类型环境的场所(论文中的图 2)。然而,没有一个类型规则有一个结论,其中类型环境在一个开销箭头下。所以,我看不出如何使用JUMP,CASE等,因为前提不能由任何其他规则导出。
这是问题,但如果有人有任何补充材料提供更多上下文是开销箭头约定,或者如果有人知道 System-F-with-join-points 类型系统的实现(GHC 的 IR 除外),那将也很有帮助。
continuations ×10
haskell ×5
scala ×3
monads ×2
arrows ×1
asynchronous ×1
c# ×1
c#-4.0 ×1
closures ×1
ghc ×1
recursion ×1
rust ×1
scheme ×1
type-systems ×1
types ×1