I’ve recently posted a question about syntactic-2.0 regarding the definition of share
. I’ve had this working in 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
However, GHC 7.8 wants -XAllowAmbiguousTypes
to compile with that signature. Alternatively, I can replace the fi
with
(ASTF sup (Internal a) -> AST sup ((Internal a) :-> Full (Internal b)) -> ASTF sup (Internal b))
which is the type implied by the fundep on SyntacticN
. This allows me to avoid the extension. Of course this is
- a very long type to add to an already-large signature
- tiresome to manually derive
- unnecessary due to the fundep
My questions are:
- Is this an acceptable use of
-XAllowAmbiguousTypes
? - In general, when should this extension be used? An answer here suggests “it is almost never a good idea”.
-
Though I’ve read the docs, I’m still having trouble deciding if a constraint is ambiguous or not. Specifically, consider this function from Data.Syntactic.Sugar:
sugarSym :: (sub :<: AST sup, ApplySym sig fi sup, SyntacticN f fi) => sub sig -> f sugarSym = sugarN . appSym
It appears to me that
fi
(and possiblysup
) should be ambiguous here, but it compiles without the extension. Why issugarSym
unambiguous whileshare
is? Sinceshare
is an application ofsugarSym
, theshare
constraints all come straight fromsugarSym
.