Это происходит потому, что вывод типа не очень хорошо работает с ограничениями. Он не всегда знает, нужно ли перемещать ограничения наверх или оставлять их на месте. В общем, это неразрешимая проблема, компилятор просто старается изо всех сил.
Попробуйте это в REPL:
> :t fromJust
forall a. Partial => Maybe a -> a
> :t unsafePartial
forall a. (Partial => a) -> a
> :t unsafePartial <<< fromJust
forall t2. Partial => Maybe (Partial => t2) -> t2
Посмотрите, что случилось? Композиция функции "распределила" ограничение Partial
по частям своего аргумента, поскольку неясно, применяется ли ограничение в fromJust
ко всему типу или индивидуально к a
. На самом деле это может быть ошибкой компилятора, но мне трудно сказать прямо сейчас.
Так что, если вы попытаетесь применить эту композицию функций через <$>
к getConnection
, компилятор ожидает, что getConnection
будет иметьэтот странный тип с двойной вложенностью, которого нет.
Интересно, что вы можете использовать unsafePartial
, чтобы удалить ограничение Partial
из всей функции fromJust
, а не просто возвращаемое значение:
> :t unsafePartial fromJust
forall t4. Maybe t4 -> t4
Это означает, что вы можете сделать что-то вроде этого:
pg :: forall a. PG a -> Route a
pg sql = connect $ bind (unsafePartial fromJust <$> getConnection) (runPG sql)