Haskell 在方案中对map进行curry

Haskell 在方案中对map进行curry,haskell,functional-programming,scheme,currying,Haskell,Functional Programming,Scheme,Currying,我理解Haskell语法 我想curry(部分应用)一个名为“play note”的函数,并“手动”传递一个参数,第二个参数传递一个映射 如果我能用哈斯克尔的话,我会说: playNote :: Time -> Instrument -> Int -> Int -> Int -> Int -> Music -- made up, but just to give you an idea notes = [46, 47, 35, 74] loopGo =

我理解Haskell语法

我想curry(部分应用)一个名为“play note”的函数,并“手动”传递一个参数,第二个参数传递一个映射

如果我能用哈斯克尔的话,我会说:

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版本“编译”,但并没有达到我期望的效果(curry第一个参数,然后是第二个参数)。帮忙?谢谢

编辑:
我的问题的本质是无法定义一个包含两个参数的函数,而下面的代码会产生正确的结果:

map ({some function} {some value; argument 1}) {some list; each element will be an argument 2}

回答我自己的问题:

该函数需要定义为“逐段”获取参数:换句话说,它不是真正的curry。我在上面试过,但没做对

部分应用的函数需要被描述为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
您是对的——在scheme中执行此操作的一种方法是手动创建lambda。当然,要以一种通用的、正确的方式实现,也就是检查参数的数量(不要太多!),这将是一件痛苦的事情

以下是Clojure(另一种LISP方言)是如何做到这一点的:


源头丑陋吗?大概它有用吗?当然。

除非我错过了什么,否则我不会剪下你需要的东西吗?那么问题就在于你的计划实施是否提供了它(我想大多数人都提供了)

如果你提供一个例子,说明你是如何调用循环的,以及你在时间和音高上所经过的位置,我想这会更容易看出这个计划与你的期望不符。@Davorak:尊敬的,我认为这可能会引起更多的混乱:)。我已经澄清了“心”是什么问题的关键是,部分函数应用程序不是curry,我认为您需要前者,因为如果您curry play note函数,那么根据定义,它只能接受一个参数,并返回一个接受一个参数的函数,因此使用mapMany Scheme派生语言不会传递第二个参数(如Racket或MIT Scheme)允许您的
f
函数使用此速记:
(定义((f num1)num2)(expt num1 num2)