2

Haskell の構文を理解しています。

"play-note" という関数をカリー化 (部分的に適用) し、1 つの引数を "手動" で渡し、2 つ目の引数をマップで渡したいと考えています。

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

スキームでは、これが私が持っている最高のものです:

(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

スキームバージョンは「コンパイル」しますが、私が期待することをしません(最初の引数をカリー化し、次に2番目の引数をカリー化します)。ヘルプ?ありがとう!

編集:
私の問題の本質は、次のコードが正しい結果を生成するように、2 つの引数を取る関数を定義できないことです:

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

3 に答える 3

2

私自身の質問に答えるには:

この関数は、引数を「少しずつ」受け取るように定義する必要があります。つまり、実際にはカリー化ではありません。上記を試してみましたが、うまくいきませんでした。

部分的に適用される関数は、ラムダまたはラムダのチェーンとして記述される必要があり、それぞれが渡される引数の数を正確に受け入れます (いつ受け取るかの降順で)。

実際の例:

(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
于 2011-08-24T08:05:13.780 に答える
1

その通りです。スキームでこれを行う 1 つの方法は、手動でラムダを作成することです。もちろん、これを一般的で正しい方法で実装するのは面倒です。つまり、引数の数をチェックします (多すぎてはいけません!)。

Clojure (もう 1 つの LISP 方言) での方法は次のとおりです。

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

ソースがおかしい?多分。それは機能しますか?もちろん。

于 2011-08-26T17:41:39.973 に答える
1

私が何かを見逃していない限り、 srfi-26からカットまたはキュートで必要なものが提供されませんか? 次に、スキームの実装がそれを提供するかどうかの問題です(ほとんどが提供していると思います)

于 2011-09-10T22:08:30.853 に答える