Карри для карты в схеме - PullRequest
       42

Карри для карты в схеме

2 голосов
/ 24 августа 2011

Я понимаю синтаксис Haskell.

Я хочу карри (частично применить) функцию с именем «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

На схеме вот лучшее, что у меня есть:

(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

Схемаверсия "компилируется", но не делает то, что я ожидаю (карри 1-й аргумент, затем 2-й).Помогите?Спасибо!

Редактировать:
Суть моей проблемы в том, что я не могу определить функцию, которая принимает два аргумента, таким образом, что следующий код дает правильный результат:

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

Ответы [ 3 ]

2 голосов
/ 24 августа 2011

Чтобы ответить на мой собственный вопрос:

Функция должна быть определена как получение аргументов "по частям": другими словами, это на самом деле не карри.Я пытался это выше, но не понял правильно.

Функция, которая применяется частично, должна быть описана как лямбда или цепочка лямбда-выражений, каждый из которых принимает ровно столько аргументов, которые ему будут переданы (в порядке убывания того, когда они будут получены).

Рабочий пример:

(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
1 голос
/ 11 сентября 2011

Если я что-то упустил, не предоставит ли вырез или милый из srfi-26 то, что вам нужно? Тогда вопрос только в том, обеспечивает ли это реализация вашей схемы (я думаю, что большинство так и делает)

1 голос
/ 26 августа 2011

Вы правы - один из способов сделать это в схеме - вручную создать лямбды.Это, конечно, будет сложно реализовать в общем, правильном виде, то есть проверке количества аргументов (не хочу иметь слишком много!).

Вот как это делает Clojure (другой диалект LISP):

http://clojuredocs.org/clojure_core/clojure.core/partial

Уродлив ли источник?Может быть.Это работает?Конечно.

...