Хороший ответ: Нет, то, что вы надеетесь сделать, действительно нецелесообразно. Вы можете написать экземпляр, который выглядит так, как будто он делает то, что вы хотите, возможно, в нем должны быть некоторые расширения GHC, но он не будет работать так, как вам бы хотелось.
Непосредственный ответ: Возможно, вы можете выполнить то, что хотите, используя страшное метапрограммирование на уровне типа, но это может усложниться. Это действительно не рекомендуется, если вы не абсолютно нужно, чтобы это работало по какой-то причине.
Официально экземпляры не могут действительно зависеть от других экземпляров, поскольку GHC смотрит только на «голову экземпляра» при принятии решений, а ограничения класса находятся в «контексте». Чтобы сделать что-то вроде «синонима типа класса» здесь, вам нужно написать то, что выглядит как экземпляр Monad
для всех возможных типов, что, очевидно, не имеет смысла. Вы будете перекрываться с другими экземплярами Monad
, у которых есть свои проблемы.
В дополнение ко всему, я не думаю, что такой экземпляр удовлетворяет требованиям проверки завершения для разрешения экземпляра, поэтому вам также потребуется расширение UndecidableInstances
, что означает возможность записи экземпляров, которые будут отправлять тип GHC checker в бесконечный цикл.
Если вы действительно хотите спуститься по этой кроличьей дыре, просмотрите на Oleg Kiselyov's website немного; он похож на покровителя метапрограммирования на уровне уровня в Хаскелле.
Это, конечно, забавный материал, но если вы просто хотите написать код и заставить его работать, возможно, не стоит боль.
Редактировать: Хорошо, оглядываясь назад, я преувеличил проблему здесь. Что-то вроде PhantomMonad
отлично работает как одноразовый и должен делать то, что вы хотите, учитывая расширения Overlapping
- и UndecidableInstances
GHC. Сложный материал запускается, когда вы хотите сделать что-то гораздо более сложное, чем то, что в этом вопросе. Я искренне благодарил Нормана Рэмси за то, что позвонил мне - я действительно должен был знать лучше.
Я по-прежнему не очень рекомендую делать такие вещи без уважительной причины, но это не так плохо, как я сделал это. Моя вина.
Является ли 'preturn :: a -> p b' a typo? –