无法推断(显示a10)由使用“ def”引起的

时间:2018-11-07 16:22:53

标签: haskell lens

我在这个错误上停留了很长时间。我不确定自己是否很愚蠢,但是我看不到它是从哪里来的...

数据类型Settings的定义如下:

data Settings a = Settings { 
         _nodeDrawFunction :: a -> Diagram B
       , _dynamicHead :: Measure Double
       , _dynamicThick :: Measure Double
       , _directed :: Directed
       , _horizontalOrientation :: Maybe Bool
       , _layerSpacing :: Maybe Double
       , _nodeSpacing :: Maybe Double
       , _graphPadding :: Maybe Double
       , _colF :: Maybe (Int -> Colour Double)
       , _bgOp :: Maybe Double
       , _initPos :: Maybe Int
      }

makeLenses ''Settings用于为每条记录创建镜头。 _drawNodeFunction的默认值为drawDefaultNode

当我创建一个使用镜头设置器覆盖其中一些值的函数时,它可以正常工作,例如:

test1 :: (Show a) => Graph a -> Settings a
test1 g = def & bgOp .~ Just 1

按预期工作。 Graph的类型来自库的代数图。

如果我尝试设置nodeDrawFunction,例如:

test2 :: (Show a) => Graph a -> Settings a
test2 g = def & nodeDrawFunction .~ drawDefaultNode
              & bgOp .~ Just 1

产生以下错误:

Could not deduce (Show a10) arising from a use of ‘def’
  from the context: Show a
    bound by the type signature for:
               test2 :: forall a. Show a => Graph a -> Settings a
    at Visualise/Hierarchical.hs:78:1-42
  The type variable ‘a10’ is ambiguous
  These potential instances exist:
    instance Show n => Show (Duration n) -- Defined in ‘Data.Active’
    instance Show n => Show (Era n) -- Defined in ‘Data.Active’
    instance Show n => Show (Time n) -- Defined in ‘Data.Active’
    ...plus 74 others
    ...plus 264 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the first argument of ‘(&)’, namely ‘def’
  In the first argument of ‘(&)’, namely
    ‘def & nodeDrawFunction .~ drawDefaultNode’
  In the expression:
    def & nodeDrawFunction .~ drawDefaultNode & bgOp .~ Just 1

即使我尝试将nodeDrawFunction设置为默认值(以及其他任何有效函数)。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:2)

您可能希望defdef & nodeDrawFunction .~ drawDefaultNode具有相同的类型。 nodeDrawFunction足够灵活,可以使它们具有不同的类型,Settings aSettings a10。 GHC从这个更笼统的假设开始,然后由于{不受函数中任何内容的约束,因此无法为a10选择特定类型。

一种选择是用不太普通的类型定义nodeDrawFunction

另一个选择是在def上添加类型签名以指导GHC。我认为,如果您添加-XScopedTypeVariables

(def :: Settings a) & nodeDrawFunction .~ drawDefaultNode

在没有ScopedTypeVariables的情况下,两个类型变量a被解释为不同的类型,并且在类型检查之前被赋予了不同的唯一名称。如果您在Settings中有涉及a的多个场,makeLenses将得出无法更改a的镜头,因为没有一个单场镜头可以这样做。