How these two instances overlap (including types out of scope)

I asked a question about injection functors in the context of free monads a couple of days ago . The solution proposed there, based on Γ  la Carte Data Types , uses a class that is a kind of containment relationship between functors.

-- | Class that represents the relationship between a functor 'sup' containing
-- a functor 'sub'.
class (Functor sub, Functor sup) => sub :-<: sup where
    inj :: sub a -> sup a

-- | A functor contains itself.
instance Functor f => f :-<: f where
    inj = id

-- | A functor is contained in the sum of that functor with another.
instance (Functor f, Functor g) => f :-<: (Sum f g) where
    inj = InL

-- | If a functor 'f' is contained in a functor 'g', then f is contained in the
-- sum of a third functor, say 'h', with 'g'.
instance (Functor f, Functor g, Functor h, f :-<: g) => f :-<: (Sum h g) where
    inj = InR . inj

Now consider the following data types:

type WeatherData = String

data WeatherServiceF a = Fetch (WeatherData -> a) deriving (Functor)

data StorageF a = Store WeatherData a deriving (Functor)

And a function with the following type

fetch :: (WeatherServiceF :-<: g) => Free g WeatherData

Where Freecomes from the module Control.Monad.Free.

Then, if I try to use this function as follows:

reportWeather :: Free (Sum WeatherServiceF StorageF) ()
reportWeather = do
    _ <- fetch
    return ()

I get an overlapping instance error saying:

β€’ Overlapping instances for WeatherServiceF
                            :-<: Sum WeatherServiceF StorageF
    arising from a use of β€˜fetch’
  Matching instances:
    two instances involving out-of-scope types
      instance (Functor f, Functor g) => f :-<: Sum f g

      instance (Functor f, Functor g, Functor h, f :-<: g) =>
               f :-<: Sum h g

Now I understand that the first is a valid instance, but why is the second considered a valid instance? If I create variables in the second case, I would get

instance ( Functor WeatherServiceF
         , Functor StorageF
         , Functor WeatherServiceF
         , WeatherServiceF :-<: StorageF
         ) => WeatherServiceF :-<: Sum WeatherServiceF g

, , WeatherServiceF :-<: StorageF. GHC ?

:

{-# LANGUAGE DeriveFunctor         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators         #-}
+3
1

, "" , . . , , .

, , , , . - , , , , , , .

, . , , , - , GHC , , . , , . , .

+3

Source: https://habr.com/ru/post/1689502/


All Articles