繁体   English   中英

生成此 SOP function 时,如何修复类型错误,包括“Can't quantify over Traversable”?

[英]How to fix type errors, including “Can't quantify over Traversable”, when generifying this SOP function?

我只想说我什至不确定这是否可能; 这是迄今为止我在 Haskell 中尝试过的最通用的事情。 我正在尝试制作https://stackoverflow.com/a/58890226/3096687中的applyFunc的更通用版本:

newtype SummaryFun t a = SummaryFun (t a -> a)

applyRecFun :: (Traversable t, _) => Record (SummaryFun t) _ -> t r -> r
applyRecFun func recs =
  let recs_NP :: t (NP I _) -- a list of n-ary products. I is an identity functor
      recs_NP = toNP . toRecord <$> recs
      listrecs_NP :: t (NP t _) -- turn every component into a singleton list
      listrecs_NP = liftA_NP (\(I x) -> pure x) <$> recs_NP
      listrec_NP :: NP t _ -- a single n-ary product where each component is a list
      listrec_NP = mconcat listrecs_NP
      func_NP :: NP (SummaryFun t) _ -- turn the function record into a n-ary prod
      func_NP = toNP func
      resultRec_NP_I :: NP I _ -- apply the functions to each list component
      resultRec_NP_I = liftA2_NP (\(SummaryFun f) vs -> I (f vs)) func_NP listrec_NP
   in fromRecord . fromNP $ resultRec_NP_I -- go back to the nominal record Rec

遇到的第一个问题是:

• Can't quantify over ‘t’                  
    bound by the partial type signature: recs_NP :: t (NP I _)

类似的错误也发生在其他地方。

我不能确定这会解决所有问题,因为很难重现你的问题:它需要很多我没有时间设置的包和导入(提示:将来,尽量减少您的问题在发布之前尽量减少可重复的示例)。 但是我还是要发布这个,因为我至少可以看到一个问题,并且它似乎与错误消息有关。


问题是第一行的t和第三行的t不一样,而且它们都和第五行的t不同。 依此类推,对于所有涉及t的类型签名。

默认情况下,在 Haskell2010 中,每个类型变量的 scope 只是引入它的类型签名。 如果您在另一个类型签名中使用相同的字母,它将表示完全独立的类型,尽管看起来与人眼相同。

要指定您实际上意味着t在任何地方都相同,您必须在顶部类型签名中使用forall

applyRecFun :: forall t. (Traversable t, _) => Record (SummaryFun t) _ -> t r -> r

ScopedTypeVariables扩展启用, forall关键字为类型变量t创建显式 scope 范围有不同的风格,但是当在函数的类型签名中打开时,范围的范围是 function 的整个主体。

我不确定这是否会为您解决所有问题,但至少您现在应该遇到不同的错误。

基于 Fyodor 的回答,我有一个正在编译(但尚未测试)的代码。 我不得不更改类型签名中的一些假设,例如返回包含在Maybe中的结果,并假设Traversable也是 forms 一个Semigroup 一旦我有机会按照 Fyodor 的建议正确测试和构建一个独立的示例,我将修改问题的措辞和这个答案:

newtype SummaryFun t a = SummaryFun (t a -> a)

applyRecFun :: forall r t. (Traversable t, Semigroup (t r), _) =>
  Record (SummaryFun t) _ -> t r -> Maybe r
applyRecFun func recs =
  let recsNP :: t (NP I _) -- a traversable of n-ary products. I is an identity functor
      recsNP = toNP . toRecord <$> recs
      listrecsNP :: t (NP t _) -- turn every component into a singleton traversable
      listrecsNP = liftA_NP (\(I x) -> pure x) <$> recsNP
      listrecNPmay :: Maybe (NP t _) -- a single n-ary product where each component is a traversable
      listrecNPmay = listrecsNP & (headMay &&& tailMay) & sequenceT
        <&> (\(h, t) -> foldr mappend h t)
      funcNP :: NP (SummaryFun t) _ -- turn the function record into a n-ary prod
      funcNP = toNP func
      toRec_NP_I :: NP t _ -> NP I _ -- apply the functions to each list component
      toRec_NP_I = liftA2_NP (\(SummaryFun f) vs -> I (f vs)) funcNP
   in do
    listrecNP <- listrecNPmay
    let resultRec_NP_I = toRec_NP_I listrecNP
    pure $ fromRecord . fromNP $ resultRec_NP_I -- go back to the nominal record Rec

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM