小编Ord*_*Ord的帖子

Python在嵌套函数中覆盖变量

假设我有以下python代码:

def outer():
    string = ""
    def inner():
        string = "String was changed by a nested function!"
    inner()
    return string
Run Code Online (Sandbox Code Playgroud)

我想调用outer()来返回"String被嵌套函数改变了!",但我得到了"".我得出结论,Python认为该行string = "string was changed by a nested function!"是对inner()本地新变量的声明.我的问题是:如何告诉Python它应该使用outer()字符串?我不能使用global关键字,因为字符串不是全局的,它只是在外部范围内.想法?

python scope

53
推荐指数
3
解决办法
2万
查看次数

创建一个可以使用方括号访问的python对象

我想创建一个新类,它充当对象的特殊容器类型,并且可以使用方括号访问.

例如,假设我有一个名为的类ListWrapper.假设obj是一个ListWrapper.当我说obj[0],我希望obj.access()用0作为参数调用该方法.然后,我可以回报我想要的任何东西.这可能吗?

python

39
推荐指数
2
解决办法
1万
查看次数

Haskell Monad绑定运算符混淆

好吧,所以我不是Haskell程序员,但我对Haskell背后的许多想法非常感兴趣,并且我正在研究它.但是我被困在第一个方面:我似乎无法绕过Monads,这似乎是相当基础的.我知道有一百万个关于SO的问题要求解释Monads,所以我会更加具体地说明了什么在困扰我:

我读了这篇优秀的文章(Javascript中的介绍),并认为我完全了解Monads.然后我读了Monads上的维基百科条目,看到了:

多态类型(M t)→(t→M u)→(M u)的绑定操作,其中Haskell由中缀运算符表示>> =.它的第一个参数是monadic类型的值,它的第二个参数是一个函数,它从第一个参数的基础类型映射到另一个monadic类型,其结果是在其他monadic类型中.

好的,在我引用的文章中,bind是一个仅占用一个参数的函数.维基百科说两个.我认为我对Monads的理解如下:

  1. Monad的目的是使用具有不同输入和输出类型的函数并使其可组合.它通过使用单个monadic类型包装输入和输出类型来实现此目的.
  2. Monad由两个相互关联的函数组成:bind和unit.绑定采用不可组合的函数f并返回一个新函数g,它接受monadic类型作为输入并返回monadic类型.g是可组合的.unit函数接受f期望的类型的参数,并将其包装在monadic类型中.然后可以将其传递给g,或者传递给g之类的任何函数组合.

但是肯定有一些错误,因为我的bind概念需要一个参数:一个函数.但是(根据维基百科)Haskell的绑定实际上有两个参数!我的错误在哪里?

monads haskell currying composition function-composition

32
推荐指数
3
解决办法
1万
查看次数

Haskell"申请"?

可能重复:
为什么haskell中不允许这样的函数定义?

我是Haskell世界的新手,从Lisp迁移过来.我正在努力适应Haskell根本不同的世界观,而我发现的许多令人兴奋的事情之一就是类型系统.作为一个Lisper,我想我会尝试在Haskell中实现一个在Lisp世界中非常重要的函数:apply.对于那些不知道的人,apply接受一个函数和一个参数列表,并在这些参数上调用该函数.在Scheme中,(apply + '(1 2 3))与调用相同(+ 1 2 3),并返回6.

我的Haskell代码看起来像这样:

apply x [] = x
apply f (x:xs) = apply (f x) xs
Run Code Online (Sandbox Code Playgroud)

但哈斯克尔抱怨道:

ERROR line 2 - Type error in function binding
*** Term           : apply
*** Type           : (b -> a) -> [b] -> a
*** Does not match : a -> [b] -> a
*** Because        : unification would give infinite type
Run Code Online (Sandbox Code Playgroud)

而且我认为我理解为什么.Apply的类型需要根据列表的长度而有所不同.给出一个例如3个项目的列表,apply的类型需要是:(a -> a -> a -> b) …

lisp haskell types polyvariadic

20
推荐指数
1
解决办法
7706
查看次数

C解析器如何区分类型转换和函数调用?

我正在尝试为自己的教育编写一个C语法分析器.我知道我可以使用像YACC这样的工具来简化流程,但我想从经验中尽可能多地学习,所以我从头开始.

我的问题是我应该如何处理这样的一行:

doSomethingWith((foo)(bar));
Run Code Online (Sandbox Code Playgroud)

它可能(foo)(bar)是一个类型转换,如:

typedef int foo;

void doSomethingWith(foo aFoo) { ... }

int main() {
    float bar = 23.6;

    doSomethingWith((foo)(bar));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者,它可能(foo)(bar)是一个函数调用,如:

int foo(int bar) { return bar; }

void doSomethingWith(int anInt) { ... }

int main() {
    int bar = 10;

    doSomethingWith((foo)(bar));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我看来,解析器无法单独通过查看行来确定它处理的两种情况中的哪一种.doSomethingWith((foo)(bar));这让我很烦恼,因为我希望能够将解析阶段与您实际确定的"解释"阶段分开该行typedef int foo;表示foo现在是有效类型.在我想象的场景中,Type a = b + c * d即使Type,a,b,c和d没有在任何地方定义,也会解析得很好,并且只有在实际尝试"解析"标识符时才会出现问题.

所以,我的问题是:"真正的"C解析器如何处理这个?两个阶段之间的分离是我希望只是一个天真的愿望,还是我错过了什么?

c parsing casting function-call

19
推荐指数
2
解决办法
582
查看次数

伪快速排序时间复杂度

我知道quicksort的O(n log n)平均时间复杂度.伪快速排序(当你从足够远的地方看它,具有适当高的抽象级别时只是一个快速排序),通常用于演示函数语言的简洁性如下(在Haskell中给出):

quicksort :: Ord a => [a] -> [a]
quicksort []     = []
quicksort (p:xs) = quicksort [y | y<-xs, y<p] ++ [p] ++ quicksort [y | y<-xs, y>=p]
Run Code Online (Sandbox Code Playgroud)

好的,所以我知道这件事有问题.最大的问题是它没有排序,这通常是quicksort的一大优势.即使这没关系,它仍然需要比典型的快速排序更长的时间,因为它在分区时必须进行两次列表传递,然后它会进行昂贵的附加操作以将其拼接回来.此外,选择第一个元素作为枢轴不是最佳选择.

即便考虑所有这些,这个快速排序的平均时间复杂度与标准快速排序不同吗?即,O(n log n)?因为追加和分区仍然具有线性时间复杂度,即使它们效率低下.

haskell quicksort time-complexity

15
推荐指数
2
解决办法
2066
查看次数

Typed Racket的类型推理如何工作?

Typed Racket做什么类型的推断?我在Racket邮件列表上找到了以下代码段:

Typed Racket类型系统包含许多超出Hindley/Milner风格类型系统支持的功能,因此我们无法使用该推理系统.目前,Typed Racket使用本地类型推断来推断程序中的许多类型,但我们想要推断更多类型 - 这是一个持续的研究领域.

上面的模糊使用术语"本地类型推断",我也听过"发生打字"使用了很多,但我不完全确定这些术语的含义.

在我看来,Typed Racket目前使用的类型推断系统是不必要的弱.这是我的意思的一个例子.以下不进行类型检查:

(struct: pt ([x : Real] [y : Real]))

(define (midpoint p1 p2)
  (pt (/ (+ (pt-x p1) (pt-x p2)) 2)
      (/ (+ (pt-y p1) (pt-y p2)) 2)))
Run Code Online (Sandbox Code Playgroud)

你必须明确地标注midpoint(: midpoint (pt pt -> pt)),否则你得到的错误:Type Checker: Expected pt, but got Any in: p1.为什么不能类型检查只是由此得出结论,该类型的p1p2 必须pt?这是对Racket实现类型的方式的一个基本限制(也就是说,由于某些Racket更高级的类型特性,这种推理方式实际上有时是错误的),或者这是否有可能在未来实现?

types type-inference racket typed-racket

14
推荐指数
1
解决办法
1332
查看次数

宏应该有副作用吗?

可以(或应该)宏观扩张有副作用吗?例如,这是一个实际上在编译时抓取网页内容的宏:

#lang racket

(require (for-syntax net/url))
(require (for-syntax racket/port))

(define-syntax foo
  (lambda (syntx)
    (datum->syntax #'lex
                   (port->string
                     (get-pure-port
                       (string->url
                         (car (cdr (syntax->datum syntx)))))))))
Run Code Online (Sandbox Code Playgroud)

然后,我可以做(foo "http://www.pointlesssites.com/"),它将被取代"\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\r\n\t <and so on>"

这是好习惯吗?我是不是觉得Racket只运行一次这段代码?如果我(display "running...")在宏中添加一行,它只打印一次,但我不想从一个例子中推广......

PS - 我问的原因是因为我实际上认为这有时候非常有用.例如,是一个库,允许您从Google API Discovery服务加载(在编译时)发现文档,并自动为其创建包装器.我认为,如果库实际上是从Web获取发现文档而不是本地文件,那将会非常酷.

另外,举一个具有不同副作用的宏的例子:我曾经构建了一个宏,它将一小部分Racket翻译成(eta-expanded)lambda演算(当然,它仍然可以在Racket中运行).每当宏完成翻译函数时,它都会将结果存储在字典中,以便稍后调用宏可以在自己的翻译中使用该函数定义.

macros side-effects racket

12
推荐指数
1
解决办法
550
查看次数

由关键字触发的Scheme宏,不是列表的头部

假设我想在除s-expression中第一项之外的其他内容上触发Scheme宏.例如,假设我想define用中缀样式替换:=,以便:

(a := 5) -> (define a 5)
((square x) := (* x x)) -> (define (square x) (* x x))
Run Code Online (Sandbox Code Playgroud)

实际的转变似乎非常简单.诀窍是让Scheme找到:=表达式并对它们进行宏扩展.我已经考虑过围绕使用带有标准宏的中缀语法的大部分代码,可能是:(with-infix-define expr1 expr2 ...)和标准宏遍历其主体中的表达式并执行任何必要的转换.我知道如果我采用这种方法,我必须小心避免转换实际上应该是数据的列表,例如引用列表和quasiquoted列表的某些部分.我想象的一个例子:

(with-infix-define
   ((make-adder n) := (lambda (m) (+ n m)))

   ((foo) :=
       (add-3 := (make-adder 3))
       (add-6 := (make-adder 6))
       (let ((a 5) (b 6))
           (+ (add-3 a) (add-6 b))))

   (display (foo))
   (display '(This := should not be transformed))
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是双重的:

  1. 如果我选择这with-infix-define条路线,我是否必须注意除引号和准引号之外的任何绊脚石?
  2. 我觉得有点像我正在重新发明轮子.这种类型的代码行走似乎正是标准宏扩展系统必须做的 - 唯一的区别是它们在决定是否进行任何代码转换时只查看列表中的第一项.有什么方法可以搭载现有的系统吗?

lisp macros scheme

7
推荐指数
1
解决办法
342
查看次数

如何清除clojure core.async频道?

我第一次看Clojure core.async,正在经历Rich Hickey的精彩演讲:http://www.infoq.com/presentations/clojure-core-async

我对他在演讲结束时展示的例子有疑问:

core.async Web示例

根据Rich的说法,这个例子基本上试图获得特定查询的Web,视频和图像结果.它为每个结果并行尝试两个不同的源,并为每个结果提取最快的结果.并且整个操作可能不会超过80毫秒,所以如果我们不能在80毫秒内获得例如图像结果,我们就会放弃."最快"的功能会创建并返回一个新频道,并启动两个过程来竞赛以检索结果并将其放在频道上.然后我们将第一个结果从"最快"的通道中取出并将其打到c通道上.

我的问题:在我们取得第一个结果之后,这三个临时的,未命名的"最快"频道会发生什么?据推测,仍有一个停止过程试图将第二个结果放到通道上,但是没有人在听,所以它从未实际完成.由于频道从未与任何东西绑定,因此我们似乎无法再对它做任何事情.流程和渠道是否会"意识到"没有人关心他们的结果并自我清理?或者我们基本上只是"泄漏"此代码中的三个通道/进程?

clojure core.async

7
推荐指数
1
解决办法
1050
查看次数