我無法使用任何使用likeDerivingVia型別的型別自動派生實體;我從編譯器得到的錯誤是:optics-corePrism'
src/Main.hs:24:13-19: error:
? Couldn't match type ‘Foo’ with ‘Stringable Foo’
arising from the coercion of the method ‘mkPrism’
from type ‘MyPrism (Stringable Foo)’ to type ‘MyPrism Foo’
? When deriving the instance for (MkPrism Foo)
|
24 | deriving (MkPrism) via (Stringable Foo)
| ^^^^^^^
有問題的型別是:
newtype MyPrism a
= MyPrism (Prism' String a)
如果我Prism'用它的底層表示替換型別,編譯成功,即:
newtype MyPrism a
= MyPrism (a -> String, String -> Maybe a)
- 為什么我在使用時會看到強制問題
Prism'?是不是因為建構式沒有被Optic包匯出? - 解決這個問題的常用方法是什么?
你可以在這里看到完整的程式來重現這個:https ://github.com/srid/q-optics-coercion/blob/f1e3df5e1c5c0e4a51eacb6439fb8c627e4c7bd5/src/Main.hs ...如果你安裝了Nix,你可以bin/run在這個運行回購。
編輯:一旦 I import Optics.Internal.Optic,錯誤訊息變為:
src/Main.hs:25:13-19: error:
? Couldn't match representation of type ‘p i Foo Foo’
with that of ‘p i (Stringable Foo) (Stringable Foo)’
arising from the coercion of the method ‘mkPrism’
from type ‘MyPrism (Stringable Foo)’ to type ‘MyPrism Foo’
? When deriving the instance for (MkPrism Foo)
|
25 | deriving (MkPrism) via (Stringable Foo)
|
uj5u.com熱心網友回復:
一般來說,profunctor optics(例如在lensandoptics包中使用的那些)不是直接強制的。粗略地說,棱鏡的內部表示類似于:
newtype Prism' s a
= Prism' (forall p f. (Choice p, Applicative f) => p a (f a) -> p s (f s))
(嗯,至少這就是它的用途Control.Lens。對于Optics.Core,它可能會更復雜一些。)
這里的問題是a和在這種型別中s顯示為更高種類的型別變數(f和p)的引數。因此,它們的“角色”是名義上的(有關原因,請參閱GHC 手冊中的角色推斷部分),并且這些名義角色防止直接強制。
幸運的是,其中有一些功能Optics.Coerce旨在處理這個問題。您將無法MyPrism直接通過 newtype 派生型別,但您應該能夠撰寫:
instance MkPrism Foo where
mkPrism = MyPrism . coerceA . coerceB $ p
where MyPrism p = mkPrism :: MyPrism (Stringable Text)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/446078.html
