簡體   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