Вопрос. Есть ли способ заставить этот код работать без явной подписи типа?
Код. Во-первых, у меня есть гораздо более приятный на практике альтернативный класс MonadTrans
, вдохновленный Data.Newtype
. Это выглядит так,
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Alt.Control.Monad.Trans where
import Control.Monad
class (Monad ????, Monad (BaseMonad ????)) => MonadTrans (???? :: * -> *) where
type BaseMonad ???? :: * -> *
lift :: (BaseMonad ????) α -> ???? α
Затем у меня есть класс A
с методом foo
, и если некоторая базовая монада M
является A
, то любая преобразованная монада T M
также является A
. В коде
class A ???? where
foo :: String -> ???? ()
instance (A (BaseMonad ????), MonadTrans ????) => A ???? where
foo n = lift $ foo n
Однако, если я сейчас хочу создать ярлык для foo
с заменой первого аргумента, то мне нужна явная сигнатура типа, иначе стек контекста компилятора переполнится.
minimize_call :: A ???? => ???? ()
minimize_call = foo "minimize"
Возможная информация, которая поможет сделать вывод. Допустим, у нас есть связанный тип B :: * -> *
. Я думаю, что я хочу сказать компилятору, что B
удовлетворяет B t /= t
, B (B t) /= B t
и т. д., т.е. B
в некотором роде "монотонный" - что погоня за связанными типами эквивалентна удалению оберток нового типа, и он должен знать, что он не может удалить оболочки нового типа навсегда , следовательно, необходимо добавить контекст A
в подпись.
MonadTrans
... на данный момент, допустим, он производит более чистый код, но я думаю, что была более существенная причина. - person gatoatigrado   schedule 16.02.2012minimize_call
не должно быть каким-то фиксированным значением, а не полиморфной константой (или, может быть, вы можете сделать его полиморфным, я не уверен)? Если у него есть какой-то один фиксированный тип, я бы предпочел это задокументировать, а если нет, я бы задокументировал это. Заставлять читателя анализировать всю программу в уме, чтобы выяснить, какой тип имеетminimize_call
, кажется несколько контрпродуктивным. - person Ben   schedule 16.02.2012minimize_call
. Однако нарушение вывода типа предполагает, что что-то идет не так (с дизайном, компилятором или связью с компилятором) и, вероятно, вызовет проблемы, не говоря уже о непонятных сообщениях об ошибках. - person gatoatigrado   schedule 16.02.2012