Возможно, вы не сможете сделать именно то, что просите, но другая возможность для вашей конкретной монады - предоставить действие, которое явно делает то, что вы думаете делать с Show
. То есть, если у вас есть:
data M a = {- ... -}
instance Monad M where -- notice: no Show constraint
{- ... -}
Тогда вы могли бы дополнительно предоставить какое-то действие:
report :: Show a => M a -> M a
Я не могу придумать, как правильно использовать этот шаблон с Show
, но я знаю похожий пример, в котором вы могли бы захотеть ограничение Ord
. Настройка заключается в том, что вы хотите сделать монаду недетерминированной (например, [a]
), но без дубликатов (например, Set a
). Для удаления дубликатов требуется некоторый контекст, такой как Eq
или Ord
, но мы не можем требовать этого при каждой операции return
/ >>=
. Поэтому вместо этого мы требуем, чтобы пользователь явно пометил точки, где дубликаты должны быть объединены:
newtype Setlike a = Setlike { toList :: [a] }
instance Monad Setlike where
return x = Setlike [x]
Setlike xs >>= f = [y | x <- xs, let Setlike ys = f x, y <- ys]
collapse :: Ord a => Setlike a -> Setlike a
collapse = Setlike . Data.Set.toList . Data.Set.fromList . toList
Это можно использовать так:
valuesOfInterest = collapse $ do
v1 <- allValues
v2 <- allValues
doSomethingInteresting v1 v2
Тогда, даже если какое-либо спаривание v1
и v2
приведет к одинаковому значению интереса, это значение появится в результате только один раз.
Возможно, для вашего случая использования возможен аналогичный трюк.