在Scheme中柯里化地图

发布于 2024-11-30 21:07:29 字数 1248 浏览 1 评论 0原文

我理解 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沦落红尘 2024-12-07 21:07:29

回答我自己的问题:

该函数需要被定义为“零散”地接受参数:换句话说,它并不是真正的柯里化。我在上面尝试过,但没有得到正确的结果。

部分应用的函数需要被描述为 lambda 或 lambda 链,每个 lambda 都准确接受将要传递的参数数量(按接收时间的降序排列)。

一个有效的示例:

(define nums '(3 3 1 2))
(define f
   (lambda (num1)
      (lambda (num2)
         (expt num1 num2))))
(define ans (map (f 5) nums))
(print ans)

将 f 定义为接受所有参数将不起作用:

(define f
   (lambda (num1 num2)
      (expt num1 num2))) ; Can't be curried

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:

(define nums '(3 3 1 2))
(define f
   (lambda (num1)
      (lambda (num2)
         (expt num1 num2))))
(define ans (map (f 5) nums))
(print ans)

Defining f as accepting all arguments will not work:

(define f
   (lambda (num1 num2)
      (expt num1 num2))) ; Can't be curried
唯憾梦倾城 2024-12-07 21:07:29

你是对的——在方案中执行此操作的一种方法是手动创建 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.

千仐 2024-12-07 21:07:29

除非我错过了一些东西,否则不会从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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文