私は数日前にフリーモナドのコンテキストでファンクタを注入することについてI asked a questionです。 Data Types à la Carteに基づいて、そこに提案されている解決策は、ファンクタ間の一種の包含関係を表すクラスを使用します。これらの2つのインスタンスはどのようにオーバーラップしていますか(スコープ外のタイプを含む)
-- | 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
は今、次のデータ型を考えてみます。
type WeatherData = String
data WeatherServiceF a = Fetch (WeatherData -> a) deriving (Functor)
data StorageF a = Store WeatherData a deriving (Functor)
、次のタイプ
Free
が
Control.Monad.Free
モジュールから来
fetch :: (WeatherServiceF :-<: g) => Free g WeatherData
と機能。私はこの機能を使用しようと
は、その後、次のように:私は最初は有効なインスタンスがあることを理解し、
• 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
を今すぐ:
reportWeather :: Free (Sum WeatherServiceF StorageF)()
reportWeather = do
_ <- fetch
return()
私が言って、重複・インスタンスのエラーを取得しますしかし、なぜ2番目が有効なインスタンスと考えられるのでしょうか?私は後者の場合には、変数をインスタンス化した場合、私はそれがWeatherServiceF :-<: StorageF
というのは本当ではないので、インスタンスではありません
instance (Functor WeatherServiceF
, Functor StorageF
, Functor WeatherServiceF
, WeatherServiceF :-<: StorageF
) => WeatherServiceF :-<: Sum WeatherServiceF g
になるだろう。なぜGHCはそのような例を推測していますか?
は、私は、次のインスタンスが有効になっている:
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
私はそれについて知らなかった。私は、この質問の例でこの重複するインスタンスのエラーを回避できる理由はありますか? –
もちろん、「OverlappingInstances」に頼らずに:) –