Недавно я опубликовал question о синтаксис-2.0 относительно определения share
. Я работал в GHC 7.6:
{-# LANGUAGE GADTs, TypeOperators, FlexibleContexts #-}
import Data.Syntactic
import Data.Syntactic.Sugar.BindingT
data Let a where
Let :: Let (a :-> (a -> b) :-> Full b)
share :: (Let :<: sup,
sup ~ Domain b, sup ~ Domain a,
Syntactic a, Syntactic b,
Syntactic (a -> b),
SyntacticN (a -> (a -> b) -> b)
fi)
=> a -> (a -> b) -> b
share = sugarSym Let
Однако GHC 7.8 хочет -XAllowAmbiguousTypes
скомпилировать эту подпись. В качестве альтернативы, я могу заменить fi
на
(ASTF sup (Internal a) -> AST sup ((Internal a) :-> Full (Internal b)) -> ASTF sup (Internal b))
который является типом, подразумеваемым fundep на SyntacticN
. Это позволяет мне избежать расширения. Конечно, это
- очень длинный тип для добавления в уже большую подпись
- утомительно, чтобы вручную выводить
- ненужный из-за fundep
Мои вопросы:
- Это приемлемое использование
-XAllowAmbiguousTypes
? - В общем, когда следует использовать это расширение? Ответ здесь предполагает, что "это почти никогда не является хорошей идеей".
-
Хотя я читал документы, мне все еще трудно решить, является ли ограничение неоднозначным или нет. В частности, рассмотрим эту функцию из Data.Syntactic.Sugar:
sugarSym :: (sub :<: AST sup, ApplySym sig fi sup, SyntacticN f fi) => sub sig -> f sugarSym = sugarN . appSym
Мне кажется, что
fi
(и, возможно,sup
) здесь должен быть неоднозначным, но он компилируется без расширения. ПочемуsugarSym
однозначно, аshare
-? Посколькуshare
является приложениемsugarSym
, ограниченияshare
все поступают прямо изsugarSym
.