5

使用函数依赖时,我经常点击Coverage Condition。可以用 来提升它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

我认为因为bc都由 决定a,所以更通用的代码不应该引起任何问题,所以我的问题是:

  1. UndecidableInstances在这里使用是否有任何可能的问题
  2. 我可以在不依赖的情况下对上述场景进行建模UndecidableInstances(也许使用类型族?)
4

1 回答 1

7

没有什么大的理由远离UndecidableInstances。可能发生的最糟糕的情况是类型检查器开始循环(并告诉你,我认为)。你可以让覆盖条件变得越来越聪明,但它永远不会做你想做的一切,因为那是不可判定的。

于 2012-03-21T08:37:39.813 回答