I have an enumeration type, e.g.
data MyType = A | B
And I want to be able to pass values of this type implicitly to my functions. I can do this using the ImplicitParams GHC extension like this:
type HasMyType = (?myType :: MyType)
myFun :: HasMyType => String
myFun = case ?myType of
A -> "Foo"
B -> "Bar"
But I've heard many times that it's better to use the Haskell package reflection for this task. Unfortunately, the reflection documentation doesn't explain how to write a similar code using the library. And it's not that straightforward to figure it out.
So, my question is, whether it's possible to use the reflection library to implement a similar code and to satisfy the following requirements?
- Values of
MyTypeshould be passed implicitly. - If the
HasMyTypeconstraint is not specified, the default value ofMyTypeshould be taken. - It should be possible to override the value passed via the
HasMyTypeconstraint in a single place, e.g. at the beginning of the application.
Does something like this is possible? Or what would be the closest approximation of this using the reflection library?
This answers two ways of implementing question 1. using reflection.
Using
Reifies:Haskell can't abstract over type variables yet
\@name -> ..so it uses\(Proxy :: Proxy name) -> ...The
Proxycan be removed frommyFunwherenameis supplied with visible type applications, butreifystill generates aProxywhose name must be "extracted"A simpler option (
Given) doesn't rely on type-level "names" to distinguish between different dictionaries, therefore it is more dangerous with the following warning: