Недавно я опубликовал 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.