为 Linear.V 派生包装器时出现类型检查错误
A typecheck errors in deriving wrapper for Linear.V
我正在尝试为 Linear.V 类型制作一个新类型包装器并派生有用的实例。我在尝试这个:
{-# LANGUAGE DataKinds, PolyKinds, ScopedTypeVariables,
StandaloneDeriving, FlexibleContexts, UndecidableInstances,
GeneralizedNewtypeDeriving, PartialTypeSignatures, TypeFamilies #-}
import Linear.V
import Control.Lens.At
data Foo = Foo1 | Foo2 deriving (Show, Eq)
尝试 1 - 我认为 GeneralizedNewtypeDeriving 可以,但不行:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq, Ixed)
我收到这个错误:
• Couldn't match representation of type ‘f (V n Foo)’
with that of ‘f (Bar n)’
arising from the coercion of the method ‘ix’
from type ‘Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo))’
to type ‘Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))’
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
• When deriving the instance for (Ixed (Bar n))
我已经尝试 2 使用这样的独立推导:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq)
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
deriving instance Ixed (V n Foo) => Ixed (Bar n)
但后来我得到了一个不同的错误:
• Couldn't match representation of type ‘f1 (V n Foo)’
with that of ‘f1 (Bar n)’
arising from a use of ‘GHC.Prim.coerce’
NB: We cannot know what roles the parameters to ‘f1’ have;
we must assume that the role is nominal
• In the expression:
GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
In an equation for ‘ix’:
ix
= GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
When typechecking the code for ‘ix’
in a derived instance for ‘Ixed (Bar n)’:
To see the code I am typechecking, use -ddump-deriv
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:12:1)
我不确定为什么会出现这两个错误。这能以某种方式完成吗?我对高级类型级别的功能不太熟悉,到目前为止我也无法真正手动编写这个特定的实例定义,所以我也认为这是一个解决方案。但我更愿意以某种方式使用 deriving
机制,因为它似乎更可重用。
编辑:我试过这个手动实例声明:
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
instance Ixed (Bar n) where
ix i f (Bar v) = ix i f v
但这会产生以下错误:
• Couldn't match type ‘V n Foo’ with ‘Bar n’
Expected type: f (Bar n)
Actual type: f (V n Foo)
• In the expression: ix i f v
In an equation for ‘ix’: ix i f (Bar v) = ix i f v
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
v :: V n Foo (bound at a.hs:14:15)
f :: IxValue (Bar n) -> f (IxValue (Bar n)) (bound at a.hs:14:8)
i :: Index (Bar n) (bound at a.hs:14:6)
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:14:3)
在我看来,编译器无法弄清楚 V n Foo
和 Bar n
的 Index
是 Int
。但我不确定。
你快到了。剩下的问题就是改造 ix
traversal for the underlying V n Foo
, which ultimately returns a function V n Foo -> f (V n Foo)
, into an ix
traversal for the wrapper type Bar n
, which should ultimately return a function Bar n -> f (Bar n)
. We have to "unpack" the definition of Traversal'
就知道了。
在您的代码中,ix i f v
的类型为 f (V n Foo)
,因此使用 Bar
构造函数 fmap
就足够了:
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
instance Ixed (Bar n) where
ix i f (Bar v) = fmap Bar (ix i f v)
我正在尝试为 Linear.V 类型制作一个新类型包装器并派生有用的实例。我在尝试这个:
{-# LANGUAGE DataKinds, PolyKinds, ScopedTypeVariables,
StandaloneDeriving, FlexibleContexts, UndecidableInstances,
GeneralizedNewtypeDeriving, PartialTypeSignatures, TypeFamilies #-}
import Linear.V
import Control.Lens.At
data Foo = Foo1 | Foo2 deriving (Show, Eq)
尝试 1 - 我认为 GeneralizedNewtypeDeriving 可以,但不行:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq, Ixed)
我收到这个错误:
• Couldn't match representation of type ‘f (V n Foo)’
with that of ‘f (Bar n)’
arising from the coercion of the method ‘ix’
from type ‘Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo))’
to type ‘Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))’
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
• When deriving the instance for (Ixed (Bar n))
我已经尝试 2 使用这样的独立推导:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq)
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
deriving instance Ixed (V n Foo) => Ixed (Bar n)
但后来我得到了一个不同的错误:
• Couldn't match representation of type ‘f1 (V n Foo)’
with that of ‘f1 (Bar n)’
arising from a use of ‘GHC.Prim.coerce’
NB: We cannot know what roles the parameters to ‘f1’ have;
we must assume that the role is nominal
• In the expression:
GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
In an equation for ‘ix’:
ix
= GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
When typechecking the code for ‘ix’
in a derived instance for ‘Ixed (Bar n)’:
To see the code I am typechecking, use -ddump-deriv
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:12:1)
我不确定为什么会出现这两个错误。这能以某种方式完成吗?我对高级类型级别的功能不太熟悉,到目前为止我也无法真正手动编写这个特定的实例定义,所以我也认为这是一个解决方案。但我更愿意以某种方式使用 deriving
机制,因为它似乎更可重用。
编辑:我试过这个手动实例声明:
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
instance Ixed (Bar n) where
ix i f (Bar v) = ix i f v
但这会产生以下错误:
• Couldn't match type ‘V n Foo’ with ‘Bar n’
Expected type: f (Bar n)
Actual type: f (V n Foo)
• In the expression: ix i f v
In an equation for ‘ix’: ix i f (Bar v) = ix i f v
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
v :: V n Foo (bound at a.hs:14:15)
f :: IxValue (Bar n) -> f (IxValue (Bar n)) (bound at a.hs:14:8)
i :: Index (Bar n) (bound at a.hs:14:6)
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:14:3)
在我看来,编译器无法弄清楚 V n Foo
和 Bar n
的 Index
是 Int
。但我不确定。
你快到了。剩下的问题就是改造 ix
traversal for the underlying V n Foo
, which ultimately returns a function V n Foo -> f (V n Foo)
, into an ix
traversal for the wrapper type Bar n
, which should ultimately return a function Bar n -> f (Bar n)
. We have to "unpack" the definition of Traversal'
就知道了。
在您的代码中,ix i f v
的类型为 f (V n Foo)
,因此使用 Bar
构造函数 fmap
就足够了:
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
instance Ixed (Bar n) where
ix i f (Bar v) = fmap Bar (ix i f v)