Я хочу представить концепцию верхней границы в своем коде, поэтому я создал размеченный союз:
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
и перенаправить на него реализации экземпляров класса типов и при этом предоставить функцию 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
во всех реализациях экземпляров класса типов, и код все равно будет компилироваться для типаMaybe
. - person rexcfnghk   schedule 22.02.2019Alternative
мне кажется схематичным. Предполагается, что он должен быть моноидом для каждого содержащегося типа (сempty
в качестве единицы и<|>
в качестве операции) - и, в частности, он должен иметьempty <|> x = x <|> empty = x
, чего нет у вас. - person Daniel Wagner   schedule 22.02.2019