Home > Software design >  Are visible type applications a safe alternative to `Proxy` arguments?
Are visible type applications a safe alternative to `Proxy` arguments?

Time:11-04

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.

  • Related