Fakta kecil yang diketahui adalah bahwa jika Anda mengaktifkan ekstensi bahasa yang cukup (ghc) Haskell menjadi bahasa yang ditafsirkan secara diketik secara dinamis! Misalnya program berikut mengimplementasikan penambahan.
{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}
data Zero
data Succ a
class Add a b c | a b -> c
instance Add Zero a a
instance (Add a b c) => Add (Succ a) b (Succ c)
Ini tidak terlihat seperti Haskell lagi. Untuk satu alih-alih mengoperasikan lebih dari objek, kami mengoperasikan lebih dari jenis. Setiap angka adalah jenisnya sendiri. Alih-alih fungsi kita memiliki kelas tipe. Ketergantungan fungsional memungkinkan kita untuk menggunakannya sebagai fungsi antar tipe.
Jadi bagaimana kita memanggil kode kita? Kami menggunakan kelas lain
class Test a | -> a
where test :: a
instance (Add (Succ (Succ (Succ (Succ Zero)))) (Succ (Succ (Succ Zero))) a)
=> Test a
Ini menetapkan tipe test
ke tipe 4 + 3. Jika kita membuka ini dalam ghci kita akan menemukan bahwa test
memang dari tipe 7:
Ok, one module loaded.
*Main> :t test
test :: Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero))))))
Tugas
Saya ingin Anda menerapkan kelas yang mengalikan dua angka Peano (bilangan bulat non-negatif). Angka-angka Peano akan dibangun menggunakan tipe data yang sama dalam contoh di atas:
data Zero
data Succ a
Dan kelas Anda akan dievaluasi dengan cara yang sama seperti di atas juga. Anda dapat memberi nama kelas Anda apa pun yang Anda inginkan.
Anda dapat menggunakan ekstensi bahasa ghc apa pun yang Anda inginkan tanpa biaya ke byte.
Uji Kasus
Kasing uji ini menganggap kelas Anda bernama M
, Anda dapat menamainya dengan nama lain jika Anda mau.
class Test1 a| ->a where test1::a
instance (M (Succ (Succ (Succ (Succ Zero)))) (Succ (Succ (Succ Zero))) a)=>Test1 a
class Test2 a| ->a where test2::a
instance (M Zero (Succ (Succ Zero)) a)=>Test2 a
class Test3 a| ->a where test3::a
instance (M (Succ (Succ (Succ (Succ Zero)))) (Succ Zero) a)=>Test3 a
class Test4 a| ->a where test4::a
instance (M (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))) (Succ (Succ (Succ Zero))) a)=>Test4 a
Hasil
*Main> :t test1
test1
:: Succ
(Succ
(Succ
(Succ
(Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))))))
*Main> :t test2
test2 :: Zero
*Main> :t test3
test3 :: Succ (Succ (Succ (Succ Zero)))
*Main> :t test4
test4
:: Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ
(Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))))))))))))
Dapatkan inspirasi dari Mengetik wawancara teknis
sumber
Jawaban:
130121 byte-9 byte berkat Ørjan Johansen
Cobalah online!
Ini mendefinisikan keluarga tipe tertutup untuk penambahan
(+)
dan perkalian(*)
. Kemudian kelas tipe(#)
didefinisikan yang menggunakan(*)
keluarga tipe bersama dengan batasan kesetaraan untuk mengkonversi dari dunia tipe familes ke dunia prolog typeclass.sumber
Zero
denganz
.+
berguna?139 byte
Cobalah online!
Menentukan operator tipe
*
. Setara dengan program Prolog:Potato44 dan Hat Wizard masing-masing menyimpan 9 byte. Terima kasih!
sumber
f
bukannyaSucc
.Versi Keluarga, 115 byte
Cobalah online!
Ini menggunakan keluarga tipe tertutup seperti kentang44 . Kecuali tidak seperti jawaban lain saya hanya menggunakan 1 jenis keluarga.
Ini mendefinisikan operator pada tiga jenis. Ini pada dasarnya mengimplementasikan
(a*b)+c
. Setiap kali kita ingin menambahkan argumen tangan kanan kita ke total kita malah memasukkannya ke dalam akumulator.Ini mencegah kita dari perlu mendefinisikan
(+)
sama sekali. Secara teknis Anda dapat menggunakan keluarga ini untuk mengimplementasikan penambahan dengan melakukanVersi Kelas, 137 byte
Cobalah online!
Versi kelas ini kehilangan beberapa alasan untuk versi keluarga, namun masih lebih pendek dari versi kelas terpendek di sini. Ini menggunakan pendekatan yang sama dengan versi keluarga saya.
sumber
Constraint
. Jadi, Anda harus memperbarui spesifikasi atau kembali ke formulir yang menggunakan kelas alih-alih jenis sinonim. Jika saya menggunakan tipe sinonim, saya bisa mendapatkan jawaban saya hingga 96 byte, jadi saya menghemat satu byte lebih banyak daripada Anda