У меня есть код, который часто использует функции, которые выглядят как
foo :: (MyMonad m) => MyType a -> MyOtherType a -> ListT m a
Чтобы попытаться сократить это, я написал следующий псевдоним типа:
type FooT m a = (MyMonad m) => ListT m a
GHC попросил меня включить Rank2Types (или RankNTypes), но не жаловался, когда я использовал псевдоним, чтобы сократить мой код до
foo :: MyType a -> MyOtherType a -> FooT m a
В отличие от этого, когда я написал псевдоним другого типа
type Bar a b = (Something a, SomethingElse b) => NotAsBar a b
и использовал его в отрицательном положении
bar :: Bar a b -> InsertTypeHere
GHC громко закричал на меня за то, что ошибался.
Я думаю, что у меня есть идея, что происходит, но я уверен, что смогу лучше понять ваши объяснения, поэтому у меня есть два вопроса:
- Каковы типичные псевдонимы типов/что они на самом деле означают?
- Есть ли способ получить терпение в обоих случаях?