23579


例えば引数を3つ (一般にはn個) とる函数

[code]

    (defn f [a b c] {:first a :second b :third c})
    
[/code]

があったとして，`[1 2]` (一般には長さ m (≤ n) のリストっぽいもの) が別の函数から得られるので， それに加えてもうひとつ `3`
(一般には n-m 個の引数たち) を適用して `(f 1 2 3)` の結果をえたい，というような状況を考えます．

例えば

[code]

    ((apply (partial partial f) [1 2]) 3)
    
[/code]

あるいは

[code]

    ((comp (partial apply f) conj) [2 3] 4)
    
[/code]

で所望の動作が得られるのですが，特に前者はなにをしているのかわかりづらすぎると感じます．函数の引数の途中までリストから渡したいということは稀にあるような気がします（ひょっとしてここが勘違い？）．どうするのが適切でしょうか．（最近まで
Haskell を触っていて clojure はやり始めたばかりなので，そもそも目指す方向が違うという気もします．最終的に `(f 1 2 3)`
を得られる clojure っぽい書き方が知りたいのであって，`partial` に意図してこだわっているわけではありません．よろしくお願いします）


CC BY-SA 3.0
2016-03-28T11:26:53.943
23550
2016-03-29T02:38:09.553
2901
question
clojure
`apply` を使った後に更に引数を渡したい


`((apply partial f [1 2]) 3)` ではだめですか。外側の引数もリストで来る場合は `(apply (apply partial f
[1 2]) [3 4])` 等。

`apply`を関数と考えるより、「最後の引数をスプライシングする」という操作と読み替えるとすっきりするかもしれません。例えば仮の文法として、引数がリストxsで来た時に、`(f
a b @xs)` などとするとそのリストが引数に展開される、となっていたとします。そうすると、今回やりたいことは部分適用との合わせ技で、

[code]

    ((partial f @[1 2]) 3)
    
[/code]

とか、あるいは外側もリストで来るなら

[code]

    ((partial f @[1 2]) @[3 4])
    
[/code]

となるわけです。実際には `(f x ... @xs)` とは書けませんが、`(apply f x ...
xs)`が同じ意味になるので、上の仮の記法例はそれぞれ

[code]

    ((apply partial f [1 2]) 3)
    (apply (apply partial f [1 2]) [3 4])
    
[/code]

となります。

個人的には、引数をスプライスする文法があるとわかりやすいなとは思うんですが、Lisp系言語とは相性が悪いんですよね。


CC BY-SA 3.0
2016-03-29T02:38:09.553
23579
2016-03-29T02:38:09.553
5258
23550
answer