Как обойти условие покрытия для функциональных зависимостей без использования -XUndecidableInstances

Используя функциональные зависимости, я часто сталкиваюсь с Условием покрытия . Его можно поднять с помощью UndecidableInstances , но я обычно стараюсь держаться подальше от этого расширения.

Вот несколько надуманный пример, который работает без UndecidableInstances :

{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}

data Result = Result String
  deriving (Eq, Show)

data Arguments a b = Arguments a b

class Applyable a b | a -> b where
  apply :: a -> b -> Result

instance Applyable (Arguments a b) (a -> b -> Result) where
  (Arguments a b) `apply` f = f a b

Когда я делаю тип результата более общим, условие покрытия не выполняется (следовательно, требуется UndecidableInstances ):

{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}

data Result a = Result a
  deriving (Eq, Show)

data Arguments a b = Arguments a b

class Applyable a b c | a -> b c where
  apply :: a -> b -> Result c

instance Applyable (Arguments a b) (a -> b -> Result c) c where
  (Arguments a b) `apply` f = f a b

Я подумал, что, поскольку b и c оба определены a , более общий код не должен вызывать никаких проблем, поэтому мои вопросы:

  1. Существуют ли какие-либо возможные проблемы с использованием UndecidableInstances здесь
  2. Могу ли я смоделировать вышеупомянутый сценарий, не полагаясь на UndecidableInstances (возможно, с семействами типов?)
5
задан user1078763 31 January 2012 в 08:19
поделиться