การใช้คลาสชนิด Haskell เพื่อบังคับใช้การสับเปลี่ยน


11

ฉันต้องการกำหนดคลาสประเภทสำหรับวัตถุทางเรขาคณิตที่สามารถตัดกันด้วยกัน:

class Intersect a b c | a b -> c where
  intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies

แนวคิดก็คือมีฟังก์ชั่นการตัดกันที่ใช้งานทั่วไปที่สามารถจัดการกับวัตถุประเภทต่างๆ หนึ่งสามารถจินตนาการกรณีเช่น

instance Intersect Line Plane (Maybe Point) where
  ...
instance Intersect Plane Plane (Maybe Line) where
  ...

แต่ฉันก็อยากจะประกาศด้วยว่าการตัดกันนั้นเป็นการสลับ:

instance (Intersect a b c) => Intersect b a c where
  intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances

ปัญหาคือว่าเมื่อใดก็ตามที่ผมประเมินintersect x yโดยไม่กำหนดเช่นมีรูปแบบIntersect a b cที่aเป็นประเภทของxและbเป็นประเภทของy, โปรแกรมที่จะเข้าสู่วง จำกัดสันนิษฐานว่าเกิดจากการประกาศเช่น recursive เกี่ยวกับ commutativity โดยหลักการแล้วฉันต้องการให้บางสิ่งบางอย่างintersect Egg Baconล้มเหลวในการตรวจสอบประเภทเนื่องจากไม่มีการกำหนดอินสแตนซ์ดังกล่าวไม่ใช่ดักจับฉันในวงวนไม่สิ้นสุด ฉันจะใช้สิ่งนี้ได้อย่างไร


เสียงเหมือนสิ่งที่คุณสามารถลองใช้กับตระกูลประเภท คุณอาจได้รับการตอบสนองที่ดีขึ้นในการล้นสแต็ค
Benjamin Hodgson

2
นี่คือการโพสต์บล็อกเกี่ยวกับ monad ที่บังคับใช้ commutativity บางทีมันอาจช่วยได้: gelisam.blogspot.ca/2013/07/the-commutative-monad.html
Daniel Díaz Carrete

คำตอบ:


2

ขั้นแรกคุณสามารถใช้แพคเกจการสับเปลี่ยนซึ่งในกรณีนี้คุณจะต้องแก้ไขประเภทลายเซ็นของintersectต่อไปนี้ แต่มิฉะนั้นรหัสที่เหลือของคุณจะ "ทำงานได้":

instersect :: Commutative a b -> c

อย่างไรก็ตามคุณยังสามารถใช้ QuickCheck กับ hspec เพื่อเรียกใช้การทดสอบคุณสมบัติในประเภทอินสแตนซ์ทั้งหมดของคุณเพื่อให้แน่ใจว่าในความเป็นจริงการเดินทาง สิ่งนี้อาจลดค่าใช้จ่าย - คุณต้องทำเกณฑ์มาตรฐานเนื่องจากฉันไม่ทราบว่าส่วนหัวของฉันอยู่ตรงไหน ตัวอย่างเช่น

import Test.Hspec

main :: IO ()
main = hspec $ do
    describe "intersect" $ do
        parallel $ it "should commute" $ do
            property $ \x y -> intersect x y == intersect (y :: Point) (x :: Line)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.