3

出于某种原因,GHC 似乎决定我的数据类型(具有两个类型参数)完全无缘无故地实例化 Bifunctor。

最有趣的是,这仅用于告诉我该数据类型存在重叠的 Functor 实例,因为我为任何 Bifunctor(以及数据类型的特定实例)提供了 Functor 的实例化。但是,如果我尝试对其进行 bimap,它会告诉我没有 Bifunctor 的实例。

{-# LANGUAGE FlexibleInstances #-}
module BifunctorError where

import Data.Bifunctor

instance Bifunctor f => Functor (f t) where
    fmap = bimap id

data Provenance p t = Provenance p t

-- Uncomment and try to compile: Overlapping instances ???
--instance Functor (Provenance p) where
--  fmap f (Provenance p x) = Provenance p (f x)

我希望这样,因为我没有提供任何东西来表明 Provenance 实例化 Bifunctor,它不会,因此从 Bifunctor 派生的 Functor 实例应该是无关紧要的。这是 FlexibleInstances 的错误吗?

4

1 回答 1

2

在寻找匹配的类型类实例时,GHC 只查看head,而不查看条件。它匹配条件作为第二步。所以当 GHC 寻找一个Functor实例时,它看到的只是

instance (Don't care) => Functor (f t) where
instance (Don't care) => Functor (Provenance p) where

这两个实例都匹配得很好。该(Don't care)位甚至直到后来才发挥作用。所以你有一些重叠的实例,这是一个问题。

你可以在这个问题中看到更多关于这个的信息。“解决方案”是玩弄 GHC 扩展OverlappingInstances,这本身就是一个兔子洞。

于 2019-05-14T01:45:19.897 回答