Memiliki fungsi f yang mengambil argumen x 1 , x 2 ,…, x n
- yaitu. f: X 1 × X 2 ×… × X n → Y
- currying mendefinisikan ulang f sebagai fungsi mengambil argumen tunggal a 1 yang memetakan fungsi lain. Teknik ini berguna untuk aplikasi parsial, misalnya dengan pow
fungsi kari yang bisa kita tulis exp = pow(e)
.
Contoh
Dengan asumsi kita memiliki fungsi berikut f mengambil tiga argumen ( f: X 1 × X 2 × X 3 → Y ):
def f(a,b,c):
return a + b * c
Menjelajahi fungsi ini membuat kita dengan f_curry: X 1 → (X 2 → (X 3 → Y)) , jika kita sekarang memanggil fungsi itu dua kali dengan f_curry(1)(2)
kita akan mendapatkan fungsi ( h
) setara dengan yang dikembalikan berikut:
def h(c):
return 1 + 2 * c
Fungsi kari f
dapat ditulis seperti ini (Python 3):
def f_curry(a):
def g_curry(b):
def h(c):
return a + b * c
return h
return g_curry
Tantangan
Tantangan Anda adalah menjelajah fungsi seperti dijelaskan di atas, berikut adalah aturannya:
- Input akan berupa fungsi kotak hitam yang membutuhkan setidaknya 2 argumen
- Fungsi input akan selalu memiliki sejumlah argumen (tidak seperti
printf
atau mirip, catatan: Anda harus mendukung fungsi dengan sejumlah argumen ≥2) - Jika bahasa Anda menggunakan fungsi curried secara default (mis. Haskell), Anda mungkin mengharapkan fungsi input didefinisikan lebih dari N -tuple, alih-alih "fungsi urutan lebih tinggi"
- Anda dapat mengambil jumlah argumen sebagai input
- Output akan menjadi setara input kari *
- Anda dapat mengasumsikan bahwa fungsi output hanya akan:
- dipanggil dengan kurang atau sama dengan jumlah argumen yang diambil oleh fungsi input
- dipanggil dengan argumen dari tipe yang tepat
* Ini berarti input f
dengan N
argumen dan output h
yang untuk semua argumen valid a1,…,aN
itu berlaku f(a1,a2,…,aN) == h(a1)(a2)…(aN)
.
def f(a,b,c): return a + b * c
dan outputnyadef f_curry(a): def g_curry(b): def h(c): return a + b * c return h return g_curry
?f
(yang didefinisikan di suatu tempat) dan output harus setara denganf_curry
. Atau inputnyalambda a,b,c: a+b*c
dan output fungsi yang setaraf_curry
.Jawaban:
JavaScript (ES6), 35 byte
sumber
Idris , 204 byte
Cobalah online!
Kedengarannya seperti pekerjaan untuk tipe dependen! Ya, mungkin.
C adalah fungsi jenis kari. Diberikan vektor tipe a = [t 1 , t 2 ,… t n ] dan fungsi tipe T: HVect a → Type , ia mengembalikan tipe baru:
Di sini, HVect adalah tipe vektor yang heterogen dari Idris Prelude - tipe n -tupel yang elemen-elemennya dari n tipe berbeda.
c adalah fungsi yang mengambil a dan T sebagai argumen implisit, dan kemudian mengubah fungsi tipe yang tidak terburu - buru ((b: HVect a) → T b) menjadi curried
f
salah satu jenis C T .( C hanya menggambarkan apa yang ingin kita lakukan; c benar-benar melakukannya. Tapi kita tidak bisa lolos dengan tidak mendefinisikan C , karena Idris menuntut agar setiap definisi tingkat atas memiliki jenis tanda tangan.)
TIO link memberikan contoh penggunaan. Jika kita mendefinisikan suatu fungsi pada 3-tupel (Nat, Nat, String) sebagai berikut:
kemudian
uncurried [3, 4, "th"]
menghasilkan hasil yang sama denganc uncurried 3 4 "th"
. Idris menyimpulkan argumena=[Nat, Nat, String]
danT=const String
bagi kami, saya percaya.Saya mendasarkan kode ini pada inti ini oleh timjb.
sumber
HVect
default —HVect
pada dasarnya adalah tuple yang bisa Anda buka.Python 3 ,
5453 byteCobalah online!
sumber
R , 96 byte
Cobalah online!
Versi sebelumnya (97 byte)
-1 byte terima kasih kepada @JayCE
sumber
Kelapa , 54 byte
Cobalah online!
Kelapa , 40 byte
Port of Erik's Python menjawab .
Cobalah online!
sumber
Python 2 , 60 byte
Cobalah online!
Footer adalah tester yang menggunakan STDIN dengan cara berikut per baris:
[a,b,...]
)Perhatikan bahwa, sementara daftar argumen diberikan sebagai input dalam tester, pada kenyataannya, ekuivalen kari akan ditambahkan ke daftar dan daftar dikurangi oleh pemanggilan fungsi.
Versi 55 byte yang serupa telah disediakan oleh ovs :
Cobalah online!
sumber
Kembang kol , 84 byte
Cobalah online!
sumber
Perl 6 ,
4240 byteCobalah online!
-2 byte berkat b2gills Brad Gilbert .
sumber
*
, hanya perlu jika ada sesuatu setelahnya.assuming(*,1)
.Python 2 , 78 byte
Cobalah online!
sumber
Attache , 5 byte
Cobalah online!
Sederhana dibangun, sebagian besar tidak menarik. Tapi, ini versi dari awal:
Attache, 35 byte
Penjelasan:
sumber
Java 8, 46 + 318 = 364 byte
Ini adalah lambda kari (hah) yang mengambil fungsi dan argumen menghitung dan mengembalikan fungsi kari.
Cobalah secara Online
Jenis pengiriman
Fungsi input
Input fungsi adalah objek dengan metode tunggal (tidak termasuk metode yang diwarisi) yang mewakili fungsi. Perhatikan bahwa antarmuka fungsional standar tidak dapat digunakan sebagai tipe input karena fungsi (misalnya) 3 parameter harus didukung. Perhatikan juga bahwa ekspresi lambda yang dilemparkan ke
java.util.function.Function
tipe seperti standar dapat dilewatkan (metode tunggal adalahapply
).Pengecualian yang diperiksa dapat dideklarasikan pada fungsi input, tetapi mereka mungkin tidak dilempar (yaitu mereka tidak akan disebarkan ke pemanggil fungsi output). Ini dianggap dapat diterima karena antarmuka fungsional Java tidak mengizinkan pengecualian diperiksa (dan menyebarkannya akan mencegah pengajuan mengembalikan a
Function
). Pengecualian runtime (dapat diberikan kepadaRuntimeException
atauError
) diperbanyak.Fungsi output
Output dari pengajuan adalah a
java.util.function.Function<Object, Object>
. Saya mempertimbangkan untuk mengembalikan dataranObject
denganapply
metode (seperti pada input), tetapi kemudian refleksi diperlukan untuk meminta hasilnya, yang tampaknya cukup tidak nyaman untuk disangkal - khususnya, memanggil semua jalan ke bawah tidak akan mungkin lagi dalam satu ekspresi.Pemakaian
Karena pengiriman mengembalikan fungsi dari
Object
keObject
, output dapat dipanggil secara langsung (denganapply
), tetapi nilai-nilai pengembalian menengah berikutnya harus dilemparkan ke jenis yang sesuai (misalnyajava.util.function.Function<Object, Object>
) sebelum dipanggil. Konsultasikan dengan TIO untuk beberapa contoh penggunaan.Perhatikan bahwa fungsi Java (yaitu metode) bukan objek kelas satu. Jadi sintaks yang digunakan dalam bullet output dari deskripsi tantangan tidak ada artinya di Jawa. Daripada yang
f(a1, a2, a3)
kita milikif.apply(a1, a2, a3)
, dan bukan yangf(a1)(a2)(a3)
kita milikif.apply(a1).apply(a2).apply(a3)
.Keterbatasan
Ketika hasil antara diterapkan (argumen ditambahkan), hasilnya sebenarnya adalah salinan hasil asli yang dimutasi. Misalnya, dalam cuplikan ini:
baris 4 akan dicetak
4
, tetapi baris 5 akan gagal, karena pada saat ituc2
sudah memegang argumen2
dan2
(perhatikan juga ituc2 == c
). Ini melanggar semangat kari, tetapi memenuhi persyaratan khusus yang dinyatakan dalam tantangan.Tidak disatukan
Lihat TIO untuk salinan yang tidak diseragamkan.
sumber
Julia 0,6 , 48 byte
Cobalah online!
Port of @ EricTheOutgolfer menjawab Python.
sumber
APL (Dyalog Classic) ,
5857 byteCobalah online!
Sintaks pemanggilan (dengan fungsi curried
g
, argumenx1
melaluix3
, dan jumlah argumenn
):((n x1 f g) x2) x3
Membutuhkan
⎕IO←1
sumber