Given that with visible type application one can now populate ambiguous types for a value or function, can this now substitute the use of Proxy entirely?
A downside I see is that one may have to enable AllowAmbiguousTypes
, but as not allowing ambiguous type used to catch type signatures that were left ambiguous by mistake then this safety net won't be there anymore. Are there any other issues one should think about?
CodePudding user response:
In modern code, I try to avoid Proxy
as much as I can, preferring ambiguous types and type applications. I can't see any downside to doing that.
Still, if I recall correctly, there are some corner cases where we still need something like Proxy
. For instance:
class C a where name :: String
instance C Int where name = "Int"
instance C Bool where name = "Bool"
data T where
T :: forall a . C a => !(Proxy a) -> T
t1 :: T
t1 = T @Int Proxy
t2 :: T
t2 = T @Bool Proxy
nameFromT :: T -> String
nameFromT (T (Proxy :: Proxy a)) = name @a
Without Proxy
, I don't know how to bind the type to a
in the last line:
data T where
T :: forall a . C a => T
t1 :: T
t1 = T @Int
t2 :: T
t2 = T @Bool
nameFromT :: T -> String
nameFromT (T @a) = name @a
-- Error:
-- Type applications in patterns are not yet supported
In this specific case the best I can do is to resort to Dict
.
data T where
T :: forall a . Dict (C a) -> T
Still, it is still Proxy
-like in that T
now has a visible (non-type-level) argument that should not be there.