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