Reputation: 11
Is there a Haskell language extension for the type class method to "use the only potential instance available"?
I want to compile the following
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
class Foo a r where
foo :: a -> r
instance Foo a (Bool -> a) where
foo x _ = x
-- This compiles
-- bar :: Int -> Bool
-- This does not
bar :: a -> Bool
bar _ = True
use :: Bool
use = bar $ foo _5 True
where
_5 :: Int
_5 = 5
Now I get the following error:
No instance for (Foo Int (Bool -> r0))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘foo’
The type variable ‘r0’ is ambiguous
Note: there is a potential instance available:
instance Foo a (Bool -> a) -- Defined at tests/pos/Fixme.hs:9:10
But since there is only one potential instance available, is there a way to force ghc to use that instance? Or is there a way to declare some instance as a default instance when types are ambiguous?
Upvotes: 1
Views: 507
Reputation: 152682
The standard trick is to make your instance more polymorphic, thus:
instance (a ~ b, bool ~ Bool) => Foo a (bool -> b) where
foo x _ = x
This precludes you from writing other function instances, but makes it clear what types to use when a function instance is wanted. You will need to turn on the TypeFamilies
extension to do this. In your specific case you may be able to get away with just instance a ~ b => Foo a (Bool -> b)
, which would allow further function instances with other argument types, at the cost of more frequent ambiguity errors.
See a previous answer of mine for some more explanation of this trick.
Upvotes: 2