当我想阅读逻辑编程时,我总是偶然发现两种"主要"方式来做到这一点:
我现在感兴趣的是:两者之间的主要技术差异是什么?它们在方法和实现方面是非常相似的,还是采用完全不同的逻辑编程方法?他们来自哪些数学分支,理论基础是什么?
我是Haskell的初学者.假设我想编写一个函数convertKVList,该函数采用键值对的平面列表,其中一些键可能会重复,并将其转换为从键到值列表的映射,其中所有键都是唯一的.例如,在Ints 对的列表中,我想要这样的行为:
> convertKVList [(1, 2), (1, 4), (1, 3), (2, 3)]
[(1,[3,4,2]),(2,[3])]
Run Code Online (Sandbox Code Playgroud)
这似乎是一个足够普遍的任务,应该有一个库函数可以做我想要的,但是当我看时我找不到任何东西.最后,有人建议我撰写Map.toList有Map.fromListWith (++),我结束了这一点:
import Data.Map as Map (toList, fromListWith)
convertKVList :: (Ord a) => [(a, b)] -> [(a, [b])]
convertKVList ls =
(Map.toList . Map.fromListWith (++) . map (\(x,y) -> (x,[y]))) ls
Run Code Online (Sandbox Code Playgroud)
我的问题是更有经验的Haskellers,分为两部分:第一,这是你如何去做,或者是否有"更好"(更容易阅读,更有效,或两者兼而有之)的方式?
其次,我怎么能靠自己想出来呢?我知道我想要的类型[(a, b)] -> [(a, [b])],但把它放入Hoogle并没有发现任何有用的东西.而且我查看了Data.Map文档,但是既没有fromListWith也toList没有跳出来特别有帮助.那么:你会如何考虑这个问题?(我意识到这两个问题都是主观的,特别是第二个问题.)
谢谢!
这是一个一直困扰着我的问题,我想知道这里是否有人可以提供帮助.
我有一个名为lambdaLVar的PLT Redex模型,它或多或少是一个花园种类的无类型lambda演算,但扩展了包含"格子变量"或LVars的商店.LVar是一个变量,其值只能随时间增加,其中"增加"的含义由语言用户指定的部分有序集(也称为格子)给出.因此lambdaLVar实际上是一个语言系列 - 用一个格子实例化它,你得到一种语言; 有一个不同的格子,你得到另一个.你可以看看这里的代码; 重要的是lambdaLVar.rkt.
在lambdaLVar的纸上定义中,语言定义由用户指定的晶格参数化.很长一段时间,我想在Redex模型中进行相同类型的参数化,但到目前为止,我还没弄清楚如何.部分麻烦在于语言的语法取决于用户如何实例化格子:格子的元素成为语法中的终端.我不知道如何在Redex中表达格式上的抽象语法.
与此同时,我试图将lambdaLVar.rkt尽可能地模块化.该文件中定义的语言专用于特定晶格:具有max最小上限(lub)操作的自然数.(或者,相当于,自然数字排序<=.它是一个非常无聊的格子.)特定于该格子的代码的唯一部分是(define lub-op max)靠近顶部的线,并natural出现在语法中.(有一个lub元函数是根据用户指定的lub-op函数定义的.后者只是一个Racket函数,所以lub必须逃避到Racket调用lub-op.)
除非能够以一种抽象的方式实际指定lambdaLVar,这种方式对于格子的选择是抽象的,似乎我应该能够编写一个lambdaLVar的版本,其中最简单的格子 - 只有Bot和Top元素,其中Bot <= Top - 然后define-extended-language用来添加更多东西.例如,我可以定义一种名为lambdaLVar-nats的语言,它专门用于我描述的自然格点:
;; Grammar for elements of a lattice of natural numbers.
(define-extended-language lambdaLVar-nats
lambdaLVar
(StoreVal .... ;; Extend the original language
natural))
;; All we have to specify is the lub operation; leq is implicitly <=
(define-metafunction/extension lub lambdaLVar-nats …Run Code Online (Sandbox Code Playgroud) TL; DR:有没有办法重写这个基于回调的JavaScript代码来代替使用promises和generator?
我有一个使用Firefox Add-on SDK编写的Firefox扩展.与SDK一样,代码分为附加脚本和内容脚本.这两个脚本具有不同类型的权限:附加脚本可以执行奇特的操作,例如,通过js-ctypes接口调用本机代码,而内容脚本可以与网页交互.然而,附加的脚本和脚本的内容可以只用相互作用彼此通过异步消息传递接口.
我希望能够在普通的,无特权的网页上从用户脚本调用扩展代码.这可以使用一种叫做的机制来完成exportFunction,它可以让一个函数从扩展代码导出到用户代码.到现在为止还挺好. 但是,只能 这很好,除了我需要导出的函数需要使用前面提到的js-ctypes接口,这只能在附加脚本中完成.exportFunction在内容脚本中使用,而不能在附加脚本中使用.
(编辑:它原来是不是是你只能使用情况exportFunction的内容脚本,请参见下面的评论.)
为了解决这个问题,我在内容脚本中编写了一个"包装器"函数; 这个包装器是我实际导出的函数exportFunction.然后,我通过将消息传递给附加脚本,使包装函数在附加脚本中调用"真实"函数.这是内容脚本的样子; 它正在导出功能lengthInBytes:
// content script
function lengthInBytes(arg, callback) {
self.port.emit("lengthInBytesCalled", arg);
self.port.on("lengthInBytesReturned", function(result) {
callback(result);
});
}
exportFunction(lengthInBytes, unsafeWindow, {defineAs: "lengthInBytes",
allowCallbacks: true});
Run Code Online (Sandbox Code Playgroud)
这是附加脚本,其中lengthInBytes定义了"真实"版本.此处的代码侦听内容脚本以向其发送lengthInBytesCalled消息,然后调用实际版本lengthInBytes,并将结果发送回lengthInBytesReturned消息.(在现实生活中,当然,我可能不需要使用js-ctypes来获取字符串的长度;这只是一个更有趣的C库调用的替身.使用你的想象力.:))
// add-on script
// Get "chrome privileges" to access the Components object.
var {Cu, …Run Code Online (Sandbox Code Playgroud) 有人请用简单的语言解释缩减语义和PLT Redex的用法.
谢谢.
programming-languages functional-programming racket plt-redex semantics
我有以下代码:
(define rest '(((di (a) (b c)) (sh (b) (e d))) ((al (a) (b)))))
(define first '((di (a) (5)) (sh (b) (3))))
Run Code Online (Sandbox Code Playgroud)
我想得到以下列表:
(((di (a) (5)) (sh (b) (3))) ((di (a) (b c)) (sh (b) (e d))) ((al (a) (b)))))
Run Code Online (Sandbox Code Playgroud)
意思是,添加列表first,成为休息的第一个元素.
当我这样做时append,它给了我:
((di (a) (5)) (sh (b) (3)) ((di (a) (b c)) (sh (b) (e d))) ((al (a) (b))))
Run Code Online (Sandbox Code Playgroud)
而我尝试做的任何其他库函数或函数都没有帮助.
谢谢.
我想知道是否有办法在Linux进程的地址空间中写入保护每个页面(从进程本身的内部,通过
mprotect()).通过"每一页",我的意思是进程的地址空间的每个页面都可以由用户模式下运行的普通程序写入 - 所以,程序文本,常量,全局变量和堆 - 但是我会对常量,全局变量和堆很满意.我不想写保护堆栈 - 这似乎是一个坏主意.
一个问题是我不知道从哪里开始写保护内存.看一下/proc/pid/maps,它显示了给定pid使用的内存部分,它们似乎始终以地址0x08048000和程序文本开头
.(在Linux中,据我所知,进程的内存是使用底部的程序文本,然后是常量,然后是全局,然后是堆,然后是一个不同大小的空白空间,具体取决于大小堆栈或堆栈,然后堆栈从虚拟地址的内存顶部向下生长0xffffffff.)有一种方法可以告诉堆顶部的位置(通过调用sbrk(0),它只返回指向当前"break"的指针,即,堆的顶部),但不是真正告诉堆开始的方式.
如果我尝试保护所有页面0x08048000直到休息,我最终会收到mprotect: Cannot allocate memory错误.我不知道为什么mprotect要分配内存 - 而Google并不是很有帮助.有任何想法吗?
顺便说一句,我想这样做的原因是因为我想创建一个在程序运行期间写入的所有页面的列表,我能想到这样做的方法是写保护所有页面,让任何尝试的写入导致写入错误,然后实现写入错误处理程序,将页面添加到列表,然后删除写保护.我想我知道如何实现处理程序,只要我能找出要保护的页面以及如何操作.
谢谢!
在.travis.yml我的一个项目中,我根据我也在.travis.yml文件中设置的环境变量来确定要安装哪些包。它看起来像这样:
env:
- CABALVER=1.18 GHCVER=7.8.1
- CABALVER=1.18 GHCVER=7.8.2
...
before_install:
...
- travis_retry sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER
...
Run Code Online (Sandbox Code Playgroud)
这是在遗留基础设施下。我想切换到基于容器的基础设施,这意味着用以下内容替换该before_install行:
addons:
apt:
packages:
- cabal-install-$CABALVER
- ghc-$GHCVER
Run Code Online (Sandbox Code Playgroud)
...除非这不起作用,因为直到 Travis 尝试安装请求的 apt 包之后,环境变量才会设置。因此,如果我尝试使用上述内容,我会收到关于我如何尝试安装名为cabal-install-and ghc-(带有结尾连字符,但减去版本后缀)的包的错误,这当然不存在。
有没有办法在基于容器的基础设施上完成我想要的?我可以尝试一次安装所有版本,然后使用 env vars 来确定在给定的工作中使用哪个版本,但是(即使我可以防止由于在一次)为每个构建作业安装所有这些真的很慢,这将否定切换到基于容器的基础设施的目的。
我试图做一个简单的任务,多次向一个字符串附加一个数字,并希望这将构建一个字符串.
但它不起作用,每次打电话(string-append ....)似乎什么都不做.
这是我的代码:
(define myString "")
(string-append (number->string 4) myString)
(string-append (number->string 5) myString)
(string-append (number->string 6) myString)
(string-append (number->string 7) myString)
(display myString)
Run Code Online (Sandbox Code Playgroud)
这显示:
"4"
"5"
"6"
"7"
和一个空白行 (display myString)
我究竟做错了什么?
如果我以其他方式这样做它也不起作用:
(define myString "")
(string-append myString (number->string 4))
(string-append myString (number->string 5))
(string-append myString (number->string 6))
(string-append myString (number->string 7))
(display myString)
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助
根据该文档的raco test,还有一个-s是将测试子模块比其他名称选项test.但我似乎无法做到这一点.如果我有以下文件:
;; example.rkt
#lang racket
(module foo racket
(display "Hi, I'm running!"))
Run Code Online (Sandbox Code Playgroud)
然后尝试foo作为子模块名称传递给raco test结果:
$ raco test example.rkt -s foo
testing example.rkt
test: Given path #<path:-s> does not exist
context...:
/Applications/Racket v5.3.3/collects/compiler/commands/test.rkt: [running body]
/Applications/Racket v5.3.3/collects/raco/raco.rkt: [running body]
/Applications/Racket v5.3.3/collects/raco/main.rkt: [running body]
Run Code Online (Sandbox Code Playgroud)
如果我只使用这个名字test:
;; example.rkt
#lang racket
(module test racket
(display "Hi, I'm running!"))
Run Code Online (Sandbox Code Playgroud)
然后,raco test工作正常:
$ raco test example.rkt
testing example.rkt
Hi, …Run Code Online (Sandbox Code Playgroud) 我在使用Scheme和列表的一个项目中注意到了这种半怪异的行为.我设法将行为隔离到一个部分.代码是:
(define x (list 1 2 3))
(define y (list 4 5))
(define z (cons (car x) (cdr y)))
(define w (append y z))
(define v (cons (cdr x) (cdr y)))
(set-car! x 6)
(set-car! y 7)
(set-cdr! (cdr x) (list 8))
x
y
z
w
v
Run Code Online (Sandbox Code Playgroud)
给我们的输出:
(6 2 8)
(7 5)
(1 5)
(4 5 1 5)
((2 8) 5)
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释:
(set-car! x 6)更新Z?因为根据我的理解car/ cdr返回指针或引用相应的值.这真的很奇怪,我有点困惑.car/ cdr不返回引用/指针,那么最终如何set-cdr! …