Saya ingin mewakili konsep batas atas dalam kode saya, jadi saya membuat kesatuan yang terdiskriminasi:
data UpperBound a = UpperBound a | DoNotCare deriving (Eq, Read, Show)
Saya kemudian secara manual memperoleh beberapa contoh kelas tipe yang berguna (untuk tujuan pembelajaran):
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 = (<|>)
dan satu fungsi utilitas:
isWithinBound :: Ord a => a -> UpperBound a -> Bool
isWithinBound _ DoNotCare = True
isWithinBound x (UpperBound b) = x <= b
Instance kelas tipe terlihat hampir sama dengan yang untuk Maybe
(Just x
-> UpperBound x
, Nothing
-> DoNotCare
) jadi sepertinya saya jelas-jelas mengalami duplikasi yang tidak perlu di sini.
Bagaimana saya bisa 'membungkus' Maybe
dan mengarahkan implementasi instance kelas tipe ke sana dan tetap mengekspos fungsi isWithinBound
?
newtype
saja? Atau bahkan jenis sinonim jika instance Anda benar-benar identik (seperti yang terlihat). - person Robin Zigmond   schedule 22.02.2019isWithinBound
, penulisan ulang itu mudah sehingga diperlukanMaybe a
alih-alih versi khusus Anda. - person Robin Zigmond   schedule 22.02.2019UpperBound/DoNotCare
tetapi secara internal meneruskan deklarasi instance ke implementasiMaybe
. Apakah itu mungkin? - person rexcfnghk   schedule 22.02.2019UpperBound
menjadiJust
danDoNotCare
menjadiNone
di semua implementasi instance kelas tipe dan kode akan tetap dikompilasi untuk tipeMaybe
. - person rexcfnghk   schedule 22.02.2019Alternative
itu tampak samar bagi saya. Ini seharusnya menjadi monoid untuk setiap tipe yang terkandung (denganempty
sebagai unit dan<|>
sebagai operasi) -- dan khususnya seharusnya memilikiempty <|> x = x <|> empty = x
, sedangkan milik Anda tidak. - person Daniel Wagner   schedule 22.02.2019