Here's a pretty useful class:
class Foo f a where
foo :: f a
It let's me make default values for lots of types. In fact, I might not even need to know what a
is.
instance Foo Maybe a where
foo = Nothing
Now I have a Maybe a
for all a
, and I can specialize it later.
specialize :: (forall a. f a) -> f Int
specialize x = x
fooMaybe :: Maybe Int
fooMaybe = specialize foo
Hmmm....that fooMaybe
sure seems pretty specific. Let's see if I can use a context to generalize it:
fooAll :: (Foo f a) => f Int
fooAll = specialize foo
Oops! Guess not.
Foo.hs:18:21:
Could not deduce (Foo * f a1) arising from a use of `foo'
from the context (Foo * f a)
bound by the type signature for fooAll :: Foo * f a => f Int
at Foo.hs:17:11-28
So, my question is, how can I write fooAll
, the generalized version of fooMaybe
? Or, more generally, how can I universally-generalize a typeclass constraint?
No good way in current Haskell right now. The constraints package provides a type that might do what you need, although, I recently figured out how to break it. Still probably your best bet, because if someone figures out how to do it right it will probably get updated
fooAll :: Forall (Foo f) => f Int
fooAll = specialize foo_f where
foo_f :: forall a. f a
foo_f = foo \\ (inst `trans` (Sub Dict) :: () :- Foo f a)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With