พิมพ์ Haskell ไม่ได้แล้วตอนนี้?
Haskell เป็นภาษาที่มีความพิมพ์น้อย มีความคิดเกี่ยวกับข้อมูลระดับประเภทขณะนี้พิมพ์ได้อย่างมีเหตุผลมากขึ้นDataKinds
และมีวิธีการบางอย่าง ( GADTs
) เพื่อให้การแสดงเวลาทำงานกับข้อมูลระดับประเภท ดังนั้นค่าของสิ่งที่ทำในเวลาแสดงอย่างมีประสิทธิภาพในประเภทซึ่งเป็นสิ่งที่มีความหมายสำหรับภาษาที่จะพิมพ์อย่างพึ่งพา
ประเภทข้อมูลที่ง่ายได้รับการเลื่อนระดับเป็นประเภทเพื่อให้ค่าที่มีอยู่สามารถนำมาใช้ในประเภท ดังนั้นตัวอย่างตามแบบฉบับ
data Nat = Z | S Nat
data Vec :: Nat -> * -> * where
VNil :: Vec Z x
VCons :: x -> Vec n x -> Vec (S n) x
เป็นไปได้และด้วยความหมายเช่น
vApply :: Vec n (s -> t) -> Vec n s -> Vec n t
vApply VNil VNil = VNil
vApply (VCons f fs) (VCons s ss) = VCons (f s) (vApply fs ss)
ซึ่งเป็นสิ่งที่ดี โปรดทราบว่ายาวเป็นสิ่งที่คงที่อย่างหมดจดในฟังก์ชั่นที่มั่นใจว่าอินพุตและเอาต์พุตเวกเตอร์มีความยาวเดียวกันแม้ว่าความยาวที่มีบทบาทในการดำเนินการใดn
ๆ
vApply
ในทางตรงกันข้ามมันมาก trickier (กล่าวคือเป็นไปไม่ได้) ที่จะใช้ฟังก์ชั่นที่ทำให้n
สำเนาที่กำหนดx
(ซึ่งจะเป็นpure
ไปvApply
's <*>
)
vReplicate :: x -> Vec n x
เพราะมันสำคัญที่จะต้องรู้ว่าจะต้องทำสำเนากี่ชุดในเวลาทำงาน ป้อนซิงเกิลตัน
data Natty :: Nat -> * where
Zy :: Natty Z
Sy :: Natty n -> Natty (S n)
สำหรับโปรโมเตอร์ประเภทใด ๆ เราสามารถสร้างตระกูลซิงเกิลตันจัดทำดัชนีเหนือประเภทโปรโมตซึ่งอาศัยอยู่ด้วยค่าซ้ำของรันไทม์ เป็นประเภทของสำเนาเวลาทำงานของประเภทระดับNatty n
n
:: Nat
ตอนนี้เราสามารถเขียน
vReplicate :: Natty n -> x -> Vec n x
vReplicate Zy x = VNil
vReplicate (Sy n) x = VCons x (vReplicate n x)
ดังนั้นคุณจึงมีค่าระดับประเภทแอกถึงค่ารันไทม์: การตรวจสอบสำเนารันไทม์จะปรับแต่งความรู้แบบคงที่ของค่าระดับประเภท แม้ว่าข้อตกลงและประเภทจะถูกแยกออก แต่เราสามารถทำงานในลักษณะที่พึ่งพาได้โดยใช้การก่อสร้างแบบซิงเกิลเป็นอีพอกซีเรซินเพื่อสร้างพันธะระหว่างเฟส นี่เป็นวิธีที่ไกลจากการอนุญาตให้ใช้นิพจน์ในการรันแบบสุ่ม แต่มันไม่ได้เป็นอะไรเลย
น่ารังเกียจคืออะไร สิ่งที่ขาดหายไป?
ลองสร้างแรงกดดันเล็กน้อยเกี่ยวกับเทคโนโลยีนี้และดูว่าอะไรที่เริ่มต้นการโยกเยก เราอาจได้รับความคิดที่ว่าซิงเกิลควรจะจัดการได้ง่ายขึ้นโดยปริยาย
class Nattily (n :: Nat) where
natty :: Natty n
instance Nattily Z where
natty = Zy
instance Nattily n => Nattily (S n) where
natty = Sy natty
ทำให้เราเขียนพูดได้
instance Nattily n => Applicative (Vec n) where
pure = vReplicate natty
(<*>) = vApply
ใช้งานได้แล้ว แต่ตอนนี้มันหมายความว่าแบบดั้งเดิมของเราNat
ได้วางไข่สามชุด: แบบครอบครัวเดี่ยวและชั้นเดี่ยว เรามีกระบวนการที่ค่อนข้างน่าเบื่อสำหรับการแลกเปลี่ยนNatty n
ค่าและNattily n
พจนานุกรมที่ชัดเจน ยิ่งไปกว่านั้นNatty
คือNat
: เรามีการพึ่งพาบางอย่างเกี่ยวกับค่ารันไทม์ แต่ไม่ใช่ประเภทที่เราคิดถึงเป็นอันดับแรก ไม่มีการพิมพ์ภาษาอย่างเต็มที่ทำให้ประเภทขึ้นอยู่กับความซับซ้อนนี้!
ในขณะเดียวกันแม้ว่าNat
สามารถเลื่อนขั้นได้ แต่Vec
ก็ไม่สามารถทำได้ คุณไม่สามารถจัดทำดัชนีตามประเภทที่จัดทำดัชนี เต็มไปด้วยภาษาที่พิมพ์ขึ้นอยู่กับที่กำหนดไม่มีข้อ จำกัด ดังกล่าวและในอาชีพการงานของฉันในฐานะที่แสดงออกมาอย่างพึ่งพาฉันได้เรียนรู้ที่จะรวมตัวอย่างของการจัดทำดัชนีสองชั้นในการเจรจาของฉัน ยาก แต่เป็นไปได้ที่จะไม่คาดหวังให้ฉันพับขึ้นเหมือนบ้านของการ์ด มีปัญหาอะไร? ความเท่าเทียมกัน GADT ทำงานโดยการแปลข้อ จำกัด ที่คุณได้รับโดยปริยายเมื่อคุณให้ตัวสร้างชนิดส่งคืนเฉพาะลงในความต้องการสมการที่ชัดเจน แบบนี้.
data Vec (n :: Nat) (x :: *)
= n ~ Z => VNil
| forall m. n ~ S m => VCons x (Vec m x)
Nat
ในแต่ละสมการทั้งสองของเราทั้งสองฝ่ายมีชนิด
ทีนี้ลองใช้คำแปลเดียวกันกับบางสิ่งที่มีการทำดัชนีเหนือเวกเตอร์
data InVec :: x -> Vec n x -> * where
Here :: InVec z (VCons z zs)
After :: InVec z ys -> InVec z (VCons y ys)
กลายเป็น
data InVec (a :: x) (as :: Vec n x)
= forall m z (zs :: Vec x m). (n ~ S m, as ~ VCons z zs) => Here
| forall m y z (ys :: Vec x m). (n ~ S m, as ~ VCons y ys) => After (InVec z ys)
และตอนนี้เราสร้างข้อ จำกัด ที่เท่าเทียมกันระหว่างas :: Vec n x
และ
VCons z zs :: Vec (S m) x
ที่ซึ่งทั้งสองฝ่ายมีชนิดที่แตกต่างกัน แกน GHC ยังไม่พร้อมสำหรับแนวคิดนี้!
อะไรหายไป? ดีHaskell ส่วนใหญ่หายไปจากระดับประเภท ภาษาของคำศัพท์ที่คุณสามารถโปรโมตมีเพียงตัวแปรและตัวสร้างที่ไม่ใช่ GADT จริงๆ เมื่อคุณมีสิ่งเหล่านี้แล้วtype family
เครื่องจักรจะอนุญาตให้คุณเขียนโปรแกรมประเภทระดับ: บางส่วนอาจจะเป็นฟังก์ชั่นที่คุณควรพิจารณาที่จะเขียนในระดับเทอม (เช่นNat
มีการเพิ่มนอกจากนี้เพื่อให้คุณสามารถเพิ่มประเภทที่ดีVec
) แต่นั่นเป็นเพียงเรื่องบังเอิญ!
ในทางปฏิบัติสิ่งที่ขาดหายไปก็คือห้องสมุดซึ่งใช้ความสามารถใหม่ของเราในการจัดทำดัชนีตามค่า สิ่งใดFunctor
และMonad
กลายเป็นในโลกใหม่นี้กล้าหาญ? ฉันกำลังคิดเกี่ยวกับมัน แต่ยังมีอีกมากที่ต้องทำ
เรียกใช้โปรแกรมประเภทระดับ
Haskell เช่นเดียวกับภาษาการเขียนโปรแกรมที่พึ่งพาได้ส่วนใหญ่มี
ความหมายในการปฏิบัติงานสองประการ มีวิธีที่ระบบรันไทม์รันโปรแกรม (นิพจน์ที่ปิดแล้วเท่านั้นหลังจากการลบประเภทปรับให้เหมาะสมที่สุดแล้ว) และมีวิธีที่ตัวพิมพ์ดีดรันโปรแกรม (ตระกูลประเภทของคุณ "ประเภทคลาส Prolog" ของคุณพร้อมด้วยนิพจน์แบบเปิด) สำหรับ Haskell โดยปกติคุณจะไม่รวมสองโปรแกรมเข้าด้วยกันเพราะโปรแกรมที่ดำเนินการอยู่ในภาษาต่างๆ ภาษาที่พิมพ์ออกมาอย่างไม่น่าเชื่อมีรูปแบบการดำเนินการแยกจากกันและแบบคงที่สำหรับภาษาเดียวกันของโปรแกรม แต่ไม่ต้องกังวลรุ่นของรันไทม์ยังคงช่วยให้คุณทำการลบประเภทและแน่นอนการลบหลักฐาน: นั่นคือสิ่งที่ Coqการสกัดกลไกให้คุณ อย่างน้อยสิ่งที่คอมไพเลอร์ของ Edwin Brady ทำ (แม้ว่า Edwin จะลบค่าที่ทำซ้ำโดยไม่จำเป็นรวมถึงประเภทและการพิสูจน์) ความแตกต่างของเฟสอาจไม่ใช่ความแตกต่างของหมวดหมู่ประโยค
อีกต่อไป แต่มันยังมีชีวิตอยู่และดี
ภาษาที่พิมพ์ออกมาอย่างไม่ถูกต้องรวมทั้งหมดให้ตัวพิมพ์ดีดทำงานโปรแกรมโดยปราศจากความกลัวในสิ่งที่เลวร้ายยิ่งกว่าการรอนาน เมื่อ Haskell พิมพ์มากขึ้นเราต้องเผชิญกับคำถามว่ารูปแบบการดำเนินการแบบคงที่ควรเป็นอย่างไร วิธีการหนึ่งอาจเป็นการ จำกัด การใช้งานสแตติกให้กับฟังก์ชั่นทั้งหมดซึ่งจะทำให้เรามีอิสระในการเรียกใช้ แต่อาจบังคับให้เราสร้างความแตกต่าง (อย่างน้อยสำหรับโค้ดระดับประเภท) ระหว่างข้อมูลและ codata เพื่อให้เราสามารถบอกได้ว่า บังคับใช้การเลิกจ้างหรือผลิตภาพ แต่นั่นไม่ใช่วิธีการเดียว เรามีอิสระในการเลือกรูปแบบการดำเนินการที่อ่อนแอกว่าซึ่งไม่เต็มใจที่จะเรียกใช้โปรแกรมในราคาที่ทำให้สมการน้อยลงโดยการคำนวณ และนั่นคือสิ่งที่ GHC ทำ กฎการพิมพ์สำหรับ GHC core ไม่ได้กล่าวถึงทำงาน
โปรแกรม แต่เพียงเพื่อตรวจสอบหลักฐานสมการ เมื่อแปลไปที่แกนกลางตัวแก้ไขข้อ จำกัด ของ GHC จะพยายามเรียกใช้โปรแกรมระดับประเภทของคุณสร้างหลักฐานทางสีเงินเล็กน้อยว่านิพจน์ที่ให้นั้นเท่ากับรูปแบบปกติ วิธีการสร้างหลักฐานนี้เป็นสิ่งที่คาดเดาไม่ได้และไม่สมบูรณ์อย่างหลีกเลี่ยงไม่ได้: มันต่อสู้กับการเรียกดูซ้ำ ๆ อย่างน่ากลัวและนั่นอาจฉลาด สิ่งหนึ่งที่เราไม่ต้องกังวลก็คือการประมวลผลการIO
คำนวณในเครื่องพิมพ์ดีด: จำไว้ว่าเครื่องพิมพ์ดีดไม่จำเป็นต้องให้
launchMissiles
ความหมายเดียวกับที่ระบบรันไทม์!
วัฒนธรรม Hindley-Milner
ระบบพิมพ์ Hindley-Milner ประสบความสำเร็จอย่างน่าประหลาดใจในความแตกต่างสี่ประการด้วยผลข้างเคียงทางวัฒนธรรมที่โชคร้ายที่หลายคนไม่สามารถมองเห็นความแตกต่างระหว่างความแตกต่างและถือว่าความบังเอิญเป็นสิ่งที่หลีกเลี่ยงไม่ได้! ฉันกำลังพูดถึงอะไร
- คำศัพท์เทียบกับประเภท
- สิ่งที่เขียนอย่างชัดเจนเทียบกับสิ่งที่เขียนโดยนัย
- การปรากฏตัวในเวลาทำงานเทียบกับการลบออกก่อนเวลาทำงาน
- นามธรรมไม่ใช่ขึ้นอยู่กับเทียบกับปริมาณขึ้นอยู่กับ
เราคุ้นเคยกับการเขียนเงื่อนไขและประเภทการแยกที่จะอนุมาน ... แล้วจึงลบ เราคุ้นเคยกับการวัดปริมาณของตัวแปรประเภทด้วยสิ่งที่เป็นนามธรรมประเภทและการใช้งานที่เกิดขึ้นอย่างเงียบ ๆ และแบบคงที่
คุณจะได้ไม่ต้องเปลี่ยนทิศทางไกลจากวานิลลา Hindley-มิลเนอร์ก่อนที่ความแตกต่างเหล่านี้ออกมาจากการจัดตำแหน่งและที่ว่าไม่มีสิ่งที่ไม่ดี สำหรับการเริ่มต้นเราสามารถมีประเภทที่น่าสนใจมากขึ้นถ้าเราเต็มใจที่จะเขียนมันในไม่กี่แห่ง ในขณะเดียวกันเราไม่จำเป็นต้องเขียนพจนานุกรมประเภทคลาสเมื่อเราใช้ฟังก์ชั่นโอเวอร์โหลด แต่พจนานุกรมเหล่านั้นมีอยู่ (หรืออินไลน์) อย่างแน่นอนในเวลาทำงาน ในภาษาที่พิมพ์อย่างพึ่งพาเราคาดว่าจะลบมากกว่าประเภทที่รันไทม์ แต่ (เช่นเดียวกับคลาสประเภท) ว่าค่าที่อนุมานบางอย่างจะไม่ถูกลบ เช่นvReplicate
อาร์กิวเมนต์ของตัวเลขมักจะอนุมานได้จากประเภทของเวกเตอร์ที่ต้องการ แต่เรายังจำเป็นต้องรู้ในเวลาทำงาน
เราควรทบทวนตัวเลือกการออกแบบภาษาใดเนื่องจากความบังเอิญเหล่านี้ไม่ได้เกิดขึ้นอีกต่อไป? ยกตัวอย่างเช่นมันถูกต้องforall x. t
หรือเปล่าที่ Haskell ไม่มีทางยกตัวอย่างปริมาณที่ชัดเจน? หากเครื่องพิมพ์ดีดไม่สามารถคาดเดาได้x
โดย unifiying t
เราไม่มีวิธีอื่นที่จะพูดในสิ่งที่x
ต้องเป็น
ในวงกว้างเราไม่สามารถปฏิบัติต่อ "การอนุมานแบบ" เป็นแนวคิดแบบเสาหินที่เรามีทั้งหมดหรือไม่มีเลย สำหรับการเริ่มต้นเราจำเป็นต้องแยกมุมมอง "generalization" (กฎ "let" ของ Milner) ซึ่งอาศัยการ จำกัด ประเภทที่มีอยู่อย่างมากเพื่อให้แน่ใจว่าเครื่องจักรที่โง่สามารถเดาได้จากด้าน "ความเชี่ยวชาญ" ของ Milner "กฎ) ซึ่งมีประสิทธิภาพเท่ากับตัวแก้ไขข้อ จำกัด ของคุณ เราสามารถคาดหวังได้ว่าประเภทระดับบนสุดจะยากต่อการอนุมาน แต่ข้อมูลประเภทภายในจะยังคงเผยแพร่ได้ค่อนข้างง่าย
ขั้นตอนถัดไปสำหรับ Haskell
เราเห็นว่าประเภทและระดับของประเภทนั้นคล้ายคลึงกันมากขึ้น (และพวกเขาได้แชร์การเป็นตัวแทนภายในใน GHC แล้ว) เราอาจรวมมันเข้าด้วยกัน มันคงจะสนุก* :: *
ถ้าเราทำได้: เราสูญเสียความแข็งแกร่งทางตรรกะไป
นานแล้วเมื่อเราได้รับอนุญาตจากด้านล่าง แต่ประเภทของเสียง
มักเป็นสิ่งที่ต้องการน้อยกว่า เราต้องตรวจสอบ หากเราต้องมีประเภทประเภทระดับที่แตกต่างกันอย่างน้อยที่สุดเราสามารถแน่ใจได้ว่าทุกอย่างในระดับประเภทและสูงกว่าสามารถได้รับการส่งเสริม มันจะเป็นการดีมากที่จะใช้ polymorphism ที่เรามีอยู่แล้วซ้ำอีกครั้งแทนที่จะสร้าง polymorphism ที่ระดับชนิดใหม่
เราควรทำให้ระบบข้อ จำกัด ปัจจุบันเป็นเรื่องธรรมดาและทำให้ง่ายขึ้นโดยการอนุญาตให้สมการต่างกันa ~ b
ที่ชนิดของa
และ
b
ไม่เหมือนกัน syntactically (แต่สามารถพิสูจน์ได้เท่ากัน) มันเป็นเทคนิคเก่า (ในวิทยานิพนธ์ของฉันศตวรรษที่ผ่านมา) ซึ่งทำให้การพึ่งพาง่ายขึ้นมากที่จะรับมือกับ เราสามารถแสดงข้อ จำกัด ในการแสดงออกใน GADT และทำให้ผ่อนคลายข้อ จำกัด เกี่ยวกับสิ่งที่สามารถส่งเสริม
เราควรขจัดความจำเป็นในการก่อสร้างแบบซิงเกิลด้วยการนำเสนอฟังก์ชั่นแบบพึ่งพา, pi x :: s -> t
. ฟังก์ชั่นที่มีประเภทดังกล่าวสามารถนำไปใช้อย่างชัดเจนในการแสดงออกใด ๆ ของชนิดs
ที่อาศัยอยู่ในจุดตัดของภาษาประเภทและคำศัพท์ (เช่นตัวแปรตัวแปรคอนสตรัคเตอร์ที่มีมากขึ้นมาในภายหลัง) แลมบ์ดาและแอปพลิเคชันที่เกี่ยวข้องจะไม่ถูกลบในเวลาทำงานดังนั้นเราจึงสามารถเขียนได้
vReplicate :: pi n :: Nat -> x -> Vec n x
vReplicate Z x = VNil
vReplicate (S n) x = VCons x (vReplicate n x)
โดยไม่ต้องแทนที่โดยNat
Natty
โดเมนของpi
สามารถเป็นชนิดที่สามารถโปรโมตได้ดังนั้นหากสามารถเลื่อน GADT ได้เราสามารถเขียนลำดับตัวบ่งชี้เชิงปริมาณ (หรือ "telescopes" ตามที่ de Briuijn เรียกว่า)
pi n :: Nat -> pi xs :: Vec n x -> ...
เท่าที่เราต้องการ
จุดประสงค์ของขั้นตอนเหล่านี้คือ กำจัดความซับซ้อนด้วยการทำงานโดยตรงกับเครื่องมือทั่วไปมากกว่าแทนที่จะทำด้วยเครื่องมือที่อ่อนแอและการเข้ารหัส clunky การซื้อเข้ามาบางส่วนในปัจจุบันทำให้ประโยชน์ของ Haskell ประเภทที่ขึ้นต่อกันนั้นมีราคาแพงกว่าที่พวกเขาต้องการ
ยากเกินไป?
ประเภทขึ้นอยู่กับทำให้คนจำนวนมากประสาท พวกเขาทำให้ฉันเป็นกังวล แต่ฉันชอบเป็นกังวลหรืออย่างน้อยฉันก็พบว่ามันไม่ยากที่จะกังวล แต่มันก็ไม่ได้ช่วยให้มีหมอกของความไม่รู้รอบ ๆ หัวข้อ บางส่วนเป็นเพราะความจริงที่ว่าเราทุกคนยังคงมีจำนวนมากที่จะเรียนรู้ แต่ผู้สนับสนุนที่มีวิธีการที่ต่างไปจากเดิมอย่างสิ้นเชิงน้อยกว่านั้นเป็นที่รู้กันว่าจะทำให้เกิดความกลัวต่อคนที่อยู่ในความอุปการะ ฉันจะไม่ตั้งชื่อ "การพิมพ์แบบไม่ระบุชื่อ", "ทัวริงไม่สมบูรณ์", "ไม่มีการแยกเฟส", "ไม่มีการลบประเภท", "การพิสูจน์ทุกที่", ฯลฯ พิสูจน์ได้ทุกที่, ฯลฯ ตำนานยังคงอยู่แม้ว่าจะเป็นขยะ
แน่นอนว่าไม่ใช่กรณีที่โปรแกรมที่พิมพ์อย่างถูกต้องต้องได้รับการพิสูจน์ว่าถูกต้องเสมอ หนึ่งสามารถปรับปรุงสุขอนามัยขั้นพื้นฐานของโปรแกรมหนึ่งของการบังคับใช้ค่าคงที่เพิ่มเติมในประเภทโดยไม่ต้องไปถึงข้อกำหนดทั้งหมด ขั้นตอนเล็ก ๆ ในทิศทางนี้ค่อนข้างบ่อยส่งผลให้มีการค้ำประกันที่แข็งแกร่งขึ้นโดยมีภาระผูกพันในการพิสูจน์น้อยหรือไม่มีเลย มันไม่เป็นความจริงที่ว่าโปรแกรมพิมพ์ dependently ย่อมเต็มรูปแบบของบทพิสูจน์แน่นอนผมมักจะใช้เวลาการปรากฏตัวของการพิสูจน์ใด ๆ ในรหัสของฉันเป็นคิวที่จะตั้งคำถามกับคำจำกัดความของฉันตั้งคำถามกับคำจำกัดความของฉัน
สำหรับเช่นเดียวกับการเพิ่มขึ้นของ articulacy เราเป็นอิสระที่จะพูดสิ่งใหม่ที่เหม็นและยุติธรรม เช่นมีวิธีการมากมายในการกำหนดแผนผังการค้นหาแบบไบนารี แต่นั่นไม่ได้หมายความว่าไม่มีวิธีที่ดีวิธีที่ดีเป็นเรื่องสำคัญที่จะต้องไม่ทึกทักเอาว่าประสบการณ์ที่เลวร้ายนั้นไม่สามารถดีขึ้นได้แม้ว่าจะเป็นการอาตมาที่จะยอมรับก็ตาม การออกแบบคำจำกัดความที่ขึ้นอยู่กับเป็นทักษะใหม่ที่ต้องใช้การเรียนรู้และการเป็นโปรแกรมเมอร์ Haskell ไม่ได้ทำให้คุณเป็นผู้เชี่ยวชาญโดยอัตโนมัติ! และแม้ว่าบางรายการจะเหม็นทำไมคุณถึงปฏิเสธคนอื่น ๆ ถึงความเป็นอิสระ
ทำไมยังต้องกังวลกับ Haskell
ฉันชอบประเภทที่ขึ้นต่อกันจริงๆ แต่โครงการแฮ็กส่วนใหญ่ยังอยู่ใน Haskell ทำไม? Haskell มีคลาสประเภท Haskell มีห้องสมุดที่มีประโยชน์ Haskell มีการรักษาที่สามารถใช้การได้ Haskell มีผู้รวบรวมความแข็งแกร่งทางอุตสาหกรรม ภาษาที่พิมพ์อย่างพึ่งพานั้นอยู่ในขั้นตอนก่อนหน้านี้มากในการเติบโตของชุมชนและโครงสร้างพื้นฐาน แต่เราจะไปถึงที่นั่นด้วยการเปลี่ยน generational ที่แท้จริงในสิ่งที่เป็นไปได้เช่นโดย metaprogramming และประเภทข้อมูลทั่วไป แต่คุณเพียงแค่ต้องมองไปรอบ ๆ ในสิ่งที่ผู้คนกำลังทำตามขั้นตอนของ Haskell ต่อประเภทที่ต้องพึ่งพาเพื่อดูว่ามีประโยชน์มากมายที่จะได้รับจากการผลักดันภาษาในยุคปัจจุบันไปข้างหน้าเช่นกัน