ข้อเท็จจริงที่รู้จักกันเล็กน้อยคือถ้าคุณเปิดส่วนขยายภาษามากพอ (ghc) Haskell จะกลายเป็นภาษาที่แปลแบบไดนามิก! ตัวอย่างเช่นโปรแกรมต่อไปนี้ใช้การเพิ่ม
{-# 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)
มันไม่ได้ดูเหมือน Haskell อีกต่อไป สำหรับหนึ่งแทนที่จะใช้งานมากกว่าวัตถุเราดำเนินงานมากกว่าประเภท แต่ละหมายเลขเป็นประเภทของตัวเอง แทนที่จะเป็นฟังก์ชั่นเรามีคลาสประเภท ฟังก์ชันการพึ่งพาช่วยให้เราสามารถใช้พวกเขาเป็นฟังก์ชั่นระหว่างประเภท
ดังนั้นเราจะเรียกรหัสของเราได้อย่างไร เราใช้คลาสอื่น
class Test a | -> a
where test :: a
instance (Add (Succ (Succ (Succ (Succ Zero)))) (Succ (Succ (Succ Zero))) a)
=> Test a
นี่เป็นการกำหนดประเภทของtest
ประเภท 4 + 3 หากเราเปิดสิ่งนี้ขึ้นใน ghci เราจะพบว่าtest
เป็นประเภทที่ 7:
Ok, one module loaded.
*Main> :t test
test :: Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero))))))
งาน
ฉันต้องการให้คุณใช้คลาสที่คูณ Peano สองตัว (จำนวนเต็มไม่เป็นลบ) ตัวเลข Peano จะถูกสร้างขึ้นโดยใช้ชนิดข้อมูลเดียวกันในตัวอย่างด้านบน:
data Zero
data Succ a
และชั้นเรียนของคุณจะได้รับการประเมินในลักษณะเดียวกันกับข้างบนเช่นกัน คุณสามารถตั้งชื่อชั้นเรียนของคุณตามที่คุณต้องการ
คุณสามารถใช้ส่วนขยายภาษา ghc ใด ๆ ที่คุณต้องการโดยไม่มีค่าใช้จ่ายเป็นไบต์
กรณีทดสอบ
กรณีทดสอบเหล่านี้สมมติว่าคลาสของคุณมีชื่อM
คุณสามารถตั้งชื่ออย่างอื่นได้หากต้องการ
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
ผล
*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)))))))))))))))))
ดึงแรงบันดาลใจจากTyping การสัมภาษณ์ทางเทคนิค