ฉันต้องการแสดงแนวคิดเกี่ยวกับขอบเขตบนในโค้ดของฉัน ดังนั้นฉันจึงสร้างสหภาพที่เลือกปฏิบัติ:
data UpperBound a = UpperBound a | DoNotCare deriving (Eq, Read, Show)
จากนั้นฉันได้รับอินสแตนซ์คลาสคลาสที่มีประโยชน์หลายอย่างด้วยตนเอง (เพื่อการเรียนรู้):
instance Functor UpperBound where
fmap _ DoNotCare = DoNotCare
fmap f (UpperBound x) = UpperBound $ f x
instance Applicative UpperBound where
pure = UpperBound
DoNotCare <*> _ = DoNotCare
_ <*> DoNotCare = DoNotCare
(UpperBound f) <*> (UpperBound x) = UpperBound $ f x
instance Foldable UpperBound where
foldr _ s DoNotCare = s
foldr f s (UpperBound x) = f x s
instance Traversable UpperBound where
traverse _ DoNotCare = pure DoNotCare
traverse f (UpperBound x) = fmap UpperBound $ f x
instance Alternative UpperBound where
empty = DoNotCare
DoNotCare <|> x = x
x <|> DoNotCare = x
x <|> _ = x
instance Monad UpperBound where
return = pure
DoNotCare >>= _ = DoNotCare
(UpperBound x) >>= f = f x
instance MonadPlus UpperBound where
mzero = empty
mplus = (<|>)
และฟังก์ชันอรรถประโยชน์เดียว:
isWithinBound :: Ord a => a -> UpperBound a -> Bool
isWithinBound _ DoNotCare = True
isWithinBound x (UpperBound b) = x <= b
อินสแตนซ์ประเภทคลาสมีลักษณะเกือบจะเหมือนกับอินสแตนซ์สำหรับ Maybe
(Just x
-> UpperBound x
, Nothing
-> DoNotCare
) ดังนั้นดูเหมือนว่าฉันเห็นได้ชัดว่ามีการทำซ้ำโดยไม่จำเป็นที่นี่
ฉันจะ 'ตัด' Maybe
และเปลี่ยนเส้นทางการใช้งานอินสแตนซ์ typeclass ไปยังสิ่งนั้นได้อย่างไรและยังคงแสดงฟังก์ชัน isWithinBound
ได้อย่างไร
newtype
ไม่ได้หรือ หรือแม้แต่ประเภทคำพ้องความหมายหากอินสแตนซ์ของคุณเหมือนกันจริง ๆ (ตามที่ปรากฏ) - person Robin Zigmond   schedule 22.02.2019isWithinBound
การเขียนใหม่เป็นเรื่องเล็กน้อย ดังนั้นจึงต้องใช้Maybe a
แทนเวอร์ชันที่คุณกำหนดเอง - person Robin Zigmond   schedule 22.02.2019UpperBound/DoNotCare
แต่ส่งต่อภายในไปยังการประกาศอินสแตนซ์ไปยังการใช้งานMaybe
เป็นไปได้ไหม? - person rexcfnghk   schedule 22.02.2019UpperBound
ถึงJust
และDoNotCare
ถึงNone
ในการใช้งานอินสแตนซ์ typeclass ทั้งหมด และโค้ดจะยังคงคอมไพล์สำหรับประเภทMaybe
- person rexcfnghk   schedule 22.02.2019Alternative
นั้นดูไม่ชัดเจนสำหรับฉัน มันควรจะเป็น monoid สำหรับแต่ละประเภทที่มีอยู่ (โดยมีempty
เป็นหน่วยและ<|>
เป็นการดำเนินการ) - และโดยเฉพาะอย่างยิ่งมันควรจะมีempty <|> x = x <|> empty = x
ซึ่งของคุณไม่มี - person Daniel Wagner   schedule 22.02.2019