在Scheme中柯里化地图
我理解 Haskell 语法。
我想柯里化(部分应用)一个名为“play-note”的函数,并“手动”传递一个参数,并使用地图传递第二个参数。
如果我能用 Haskell 写它,我会说:
playNote :: Time -> Instrument -> Int -> Int -> Int -> Int -> Music -- made up, but just to give you an idea
notes = [46, 47, 35, 74]
loopGo = True
loop time = do mapM_ (playNote' time) notes
if loopGo then (loop (time+(second/2))) else return () -- time element removed
playNote' time pitch = playNote time drums pitch 80 11025 9 -- ignore extra args
在Scheme中,这是我得到的最好的:
(define notes '(46 47 35 74))
(define *loop-go* #t)
(define play-note-prime
(lambda (time2)
(lambda (pitch)
(play-note time2 drums pitch 80 11025 9)))) ; drums is another variable
(define loop
(lambda (time)
(map (play-note-prime time) notes)
(if *loop-go*
(callback (+ time (/ *second* 2)) 'loop (+ time (/ second 2)))))) ; time element is more sophisticated here
Scheme版本“编译”,但没有做我期望的事情(柯里化第一个参数,然后是第二个参数) )。帮助?谢谢!
编辑:
我的问题的本质是无法定义一个带有两个参数的函数,以便以下代码产生正确的结果:
map ({some function} {some value; argument 1}) {some list; each element will be an argument 2}
I understand Haskell syntax.
I want to curry (partially apply) a function called "play-note", and pass one argument "manually," and the second with a map.
If I could write it in Haskell, I'd say:
playNote :: Time -> Instrument -> Int -> Int -> Int -> Int -> Music -- made up, but just to give you an idea
notes = [46, 47, 35, 74]
loopGo = True
loop time = do mapM_ (playNote' time) notes
if loopGo then (loop (time+(second/2))) else return () -- time element removed
playNote' time pitch = playNote time drums pitch 80 11025 9 -- ignore extra args
In Scheme, here's the best I've got:
(define notes '(46 47 35 74))
(define *loop-go* #t)
(define play-note-prime
(lambda (time2)
(lambda (pitch)
(play-note time2 drums pitch 80 11025 9)))) ; drums is another variable
(define loop
(lambda (time)
(map (play-note-prime time) notes)
(if *loop-go*
(callback (+ time (/ *second* 2)) 'loop (+ time (/ second 2)))))) ; time element is more sophisticated here
The Scheme version "compiles," but doesn't do what I expect it to (curry the 1st arg, then the 2nd). Help? Thanks!
Edit:
The essence of my problem is not being able to define a function which takes two arguments, in a way that the following code produces the right result:
map ({some function} {some value; argument 1}) {some list; each element will be an argument 2}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
回答我自己的问题:
该函数需要被定义为“零散”地接受参数:换句话说,它并不是真正的柯里化。我在上面尝试过,但没有得到正确的结果。
部分应用的函数需要被描述为 lambda 或 lambda 链,每个 lambda 都准确接受将要传递的参数数量(按接收时间的降序排列)。
一个有效的示例:
将 f 定义为接受所有参数将不起作用:
To answer my own question:
The function needs to be defined as taking arguments "piecemeal": in other words, it's not really currying. I was trying that above, but wasn't getting it right.
A function which is partially applied needs to be described as a lambda or chain of lambdas, each accepting exactly the number of arguments it'll be passed (in descending order of when they will be recieved).
A working example:
Defining f as accepting all arguments will not work:
你是对的——在方案中执行此操作的一种方法是手动创建 lambda。当然,以通用、正确的方式实现这一点会很痛苦,即检查参数的数量(不想有太多!)。
Clojure(另一种 LISP 方言)的做法如下:
http://clojuredocs.org/clojure_core/clojure。 core/partial
源代码丑陋吗?或许。有效吗?当然。
You're right -- one way to do it in scheme is to manually create lambdas. This would of course be a pain to implement in a general, correct way, i.e. checking numbers of arguments (don't want to have too many!).
Here's how Clojure (another LISP dialect) does it:
http://clojuredocs.org/clojure_core/clojure.core/partial
Is the source ugly? Maybe. Does it work? Sure.
除非我错过了一些东西,否则不会从srfi-26 提供您需要的内容吗?那么这只是你的方案实现是否提供它的问题(我认为大多数都提供)
Unless I'm missing something, wouldn't cut or cute from srfi-26 provide what you need? Then its just a question of whether your scheme implementation provides it (I think that most do)