เหตุใดจึงไม่ จำกัด คลาสย่อยของ Enum ใน Haskell


9

ดูเหมือนว่าอินสแตนซ์ที่ถูกผูกมัดใด ๆ ควรมีการนำ Enum ไปปฏิบัติอย่างมีสติ ฉันไม่สามารถคิดตัวอย่างแบบส่วนตัวได้แม้ว่าจะมีบางคนที่มากับคนที่ไม่ใช่พยาธิวิทยาฉันก็จะเข้าใจว่าทำไมมันถึงไม่เป็นเช่นนั้น

จากการทำ:iสองประเภทของคลาสดูเหมือนว่าข้อยกเว้นเพียงอย่างเดียวในปัจจุบันในไลบรารีมาตรฐานคือสำหรับสิ่งอันดับซึ่งถูกผูกไว้ แต่ไม่ใช่ Enums อย่างไรก็ตาม tuple ที่ถูกผูกไว้ใด ๆ จะต้องนับจำนวนด้วยวิธีการที่มีสติด้วยการเพิ่มองค์ประกอบสุดท้ายจากนั้นล้อมรอบเมื่อมันไปถึง maxBound

การเปลี่ยนแปลงนี้อาจเกี่ยวข้องกับการเพิ่มpredBและ / nextBหรือสิ่งที่คล้ายกันเพื่อ จำกัด สำหรับวิธีที่ปลอดภัย / วนรอบเพื่อสำรวจผ่านค่า Enum ในกรณีนี้toEnum 0 :: (...)จะเท่ากับ(toEnum 0, toEnum 0, ...) :: (...)


3
ไม่สามารถตอบคำถามนี้ได้อย่างเป็นทางการ แต่ให้พิจารณาช่วงของจำนวนจริงทั้งหมดระหว่าง 0 ถึง 1 มันมีขอบเขตล่างและบนที่ชัดเจน แต่มีสมาชิกที่ไม่มีที่สิ้นสุด
Doval

@Doval นั่นคือจุดยุติธรรม อย่างไรก็ตามเดียวกันอาจจะกล่าวเกี่ยวกับตัวเลขจริงทั้งหมดในทั่วไป (สมาชิกอนันต์ uncountably) แต่Double/ Floatและทุกประเภทที่คล้ายกันดำเนินการEnumต่อไปพวกเขาก็ให้และsucc = (+ 1) fromEnum = truncateจริง ๆ แล้ววิธีการของ Haskell ทำให้เข้าใจได้จากมุมมองที่เป็นประโยชน์เช่นเดียวกับ [0, 0.5 .. ] และสิ่งที่คล้ายกันก็ใช้งานไม่ได้ดังนั้น Haskell จึงไม่ต้องกังวลเกี่ยวกับความสามารถในการนับเมื่อมาถึง Enums
อัฒภาค

1
ผมก็ไม่ทราบว่าเป็นsucc (+1)นั่นคือแปลกเพราะDoubleและFloatไม่ได้มีความแม่นยำที่ไม่มีที่สิ้นสุดและทำให้มีนับ - succจะได้รับการกำหนดให้เป็น 1 ULP
Doval

2
@Doval ฉันคิดว่าเหตุผลก็เพราะทีมแกน Haskell ต้องการให้ [1 .. ] หมายถึงสิ่งเดียวกันกับ Doubles ที่หมายถึงกับ Ints
เซมิโคลอน

@semicolon ทวีคูณและลอยไม่ใช่ตัวเลขจริง (เช่นไม่สามารถเก็บ PI ในคู่โดยไม่สูญเสียความแม่นยำบางอย่าง) ดังนั้นพวกเขาจึงนับได้
jk

คำตอบ:


8

ตัวอย่างที่ใช้งานได้จริงอย่างหนึ่งที่ฉันชอบมาจากโลกแห่งการเขียนโปรแกรมภาษา: ชุดของประเภทในระบบ OO นั้นมีขอบเขตและไม่ต่อเนื่อง แต่ไม่สามารถนับได้และมีการเรียงลำดับบางส่วน

<:สั่งซื้อบางส่วนในคำถามคือความสัมพันธ์ subtyping ขอบเขตด้านบนจะเป็นประเภทสูงสุด (ซึ่งการโทร C # objectและการโทรScala Any) และขอบเขตล่างจะเป็นประเภทด้านล่าง (Scala's Nothing; C # / Java ไม่เทียบเท่าที่จะพูดถึง)

instance Enum Typeแต่มีวิธีการที่จะระบุประเภททั้งหมดที่อยู่ในระบบการพิมพ์ไม่ดังนั้นคุณไม่สามารถเขียน สิ่งนี้ควรมีความชัดเจน: ผู้ใช้สามารถเขียนประเภทของตัวเองดังนั้นจึงไม่มีทางรู้ว่าพวกเขาจะต้องล่วงหน้าอะไร คุณสามารถระบุประเภททั้งหมดในโปรแกรมที่กำหนด แต่ไม่ใช่ในระบบทั้งหมด

ในทำนองเดียวกัน (ตามคำนิยามที่เหมาะสมบาง subtyping) <:คือสะท้อนสกรรมกริยาและ antisymmetric แต่ไม่ทั้งหมด <:มีคู่ของประเภทที่ไม่เกี่ยวข้องกันโดยมี ( CatและDogเป็นทั้งประเภทย่อยAnimalแต่ไม่มีประเภทย่อยของอีก)


สมมติว่าเรากำลังเขียนคอมไพเลอร์สำหรับภาษา OO อย่างง่าย นี่คือการแสดงประเภทในระบบของเรา:

data Type = Bottom | Class { name :: String, parent :: Type } | Top

และคำจำกัดความของความสัมพันธ์ของประเภทย่อย:

(<:) :: Type -> Type -> Bool
Bottom <: _ = True
Class _ _ <: Bottom = False
Class n t <: s@(Class m _)
    | n == m = True  -- you can't have different classes with the same name in this hypothetical language
    | otherwise = t <: s  -- try to find s in the parents of this class
Class _ _ <: Top = True
Top <: Top = True
Top <: _ = False

สิ่งนี้ยังทำให้เรามีความสัมพันธ์ที่พิเศษยิ่งขึ้น

(>:) :: Type -> Type -> Bool
t >: s = s <: t

คุณยังสามารถค้นหาขอบเขตบนสุดของสองประเภท

lub :: Type -> Type -> Type
lub Bottom s = s
lub t Bottom = t
lub t@(Class _ p) s@(Class _ q) =
    | t >: s = t
    | t <: s = s
    | p >: s = p
    | t <: q = q
    | otherwise = lub p q
lub Top _ = Top
lub _ Top = Top

การใช้สิทธิ: แสดงให้เห็นว่าTypeรูปแบบกระโดด poset สมบูรณ์สองวิธีภายใต้และอยู่ภายใต้<:>:


ขอบคุณมาก! นั่นตอบคำถามของฉันอย่างสมบูรณ์และยังตอบคำถามติดตามของฉันเกี่ยวกับ Ord Eq จะมีปัญหาคล้ายกันไหม? โดยที่ประเภทที่ไม่สามารถใช้ได้อาจมี maxBound หรือ minBound ในกรณีนี้ควร Cat == สุนัขเพิ่งกลับเท็จเนื่องจากเป็นคลาสที่แตกต่างกันหรือจะไม่สามารถตัดสินใจได้เพราะตำแหน่งต้นไม้ไม่ได้อยู่เหนือหรือใต้อื่น ๆ ?
เซมิโคลอน

สั่งหมายถึงความเท่าเทียมกัน - x == y = x <= y && y <= xเพียงแค่กำหนด ถ้าผมถูกออกแบบระดับฉันมีPoset class Eq a => Poset aยืนยัน Google อย่างรวดเร็วว่าคนอื่น ๆ ได้มีความคิดเดียวกัน
Benjamin Hodgson

ขออภัยคำถามของฉันไม่ชัดเจน สิ่งที่ฉันหมายถึงคือว่า Eq ที่ถูก จำกัด โดยนัยถึงแม้ว่ามันจะไม่ได้หมายความว่า Ord
semicolon

@semicolon อีกครั้งไม่มีความสัมพันธ์ระหว่างสองคลาส พิจารณาว่าdata Bound a = Min | Val a | Maxจะเพิ่มประเภทaด้วย+∞และ-∞องค์ประกอบใด โดยการก่อสร้างBound aสามารถสร้างเป็นตัวอย่างได้เสมอBoundedแต่มันก็น่าจะเป็นที่เท่าเทียมกันถ้าประเภทพื้นฐานaคือ
Benjamin Hodgson

ก็พอใช้ได้พอสมควร ฉันเดาว่าตัวอย่างหนึ่งอาจเป็นฟังก์ชั่นที่รับและคืนค่าประเภทDoubleซึ่งconst (1/0)อยู่ที่ไหนmaxBoundและconst (negate 1/0)เป็นminBoundแต่นั้น\x -> 1 - xและ\x -> x - 1หาที่เปรียบมิได้
อัฒภาค

4

มันเป็นเพราะการดำเนินงานมีความเป็นอิสระดังนั้นการรวมเข้ากับความสัมพันธ์ของคลาสย่อยจึงไม่ได้ซื้ออะไรให้คุณเลย สมมติว่าคุณต้องการสร้างประเภทที่กำหนดเองซึ่งนำไปใช้BoundedอาจมีDoublesข้อ จำกัด ระหว่าง max และ min แต่คุณไม่จำเป็นต้องมีการEnumดำเนินการใด ๆ ถ้าBoundedเป็นคลาสย่อยคุณจะต้องนำEnumฟังก์ชั่นทั้งหมดมาใช้เพื่อรวบรวมมัน

ไม่สำคัญว่าจะมีการนำไปใช้อย่างสมเหตุสมผลEnumหรือประเภทของประเภทอื่น ๆ หากคุณไม่ต้องการใช้งานจริงคุณไม่ควรถูกบังคับให้ใช้งาน

คมชัดนี้มีการพูด, และOrd Eqที่นั่นการOrdดำเนินการขึ้นอยู่กับEqสิ่งนั้นดังนั้นจึงเหมาะสมที่จะต้องใช้คลาสย่อยเพื่อหลีกเลี่ยงการทำซ้ำและสร้างความมั่นคง


1
ในกรณีเหล่านั้นมันเป็นส่วนหนึ่งของคำนิยาม พระทุกคนยังเป็นผู้สมัครและฟังก์ชั่นตามคำจำกัดความดังนั้นคุณจึงไม่สามารถปฏิบัติตามสัญญา "monad" โดยไม่ทำตามคนอื่นได้ ฉันไม่คุ้นเคยกับคณิตศาสตร์เพียงพอที่จะรู้ว่ามันเป็นความสัมพันธ์ขั้นพื้นฐานหรือคำจำกัดความที่กำหนด แต่อย่างใดตอนนี้เราติดอยู่กับมันแล้ว
Karl Bielefeldt

6
@semicolon เอกสารสำหรับBoundedพูดว่า "Ord ไม่ใช่ superclass ของ Bounded เนื่องจากประเภทที่ไม่ได้สั่งทั้งหมดอาจมีขอบเขตบนและล่าง"
Benjamin Hodgson

1
@BenjaminHodgson ไม่ได้คิดถึงประเภทที่สั่งบางส่วน +1 สำหรับตัวอย่างที่ไม่ใช่พยาธิวิทยาและสำหรับการอ้างอิงเอกสาร
Doval

1
@semicolon ตัวอย่างของการสั่งซื้อบางส่วนจากโลกของคอมพิวเตอร์อาจมีการพิมพ์ย่อยในภาษา OO เขียน<:สำหรับเป็นชนิดย่อยของ , ∀ T S. T <: S ∨ S <: Tไม่ถือ (เช่นint !<: bool ∧ bool !<: int) คุณน่าจะเจอกับสิ่งนี้ถ้าคุณเขียนคอมไพเลอร์
Benjamin Hodgson

1
@BenjaminHodgson อ่า ตัวอย่างเช่นถ้า A เป็น superclass ของ B และ C และ D เป็น subclass ของ B และ C ดังนั้น B และ C นั้นหาที่เปรียบมิได้ แต่ A และ D เป็น max / min หรือไม่
semicolon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.