我正在尝试为
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)
Index
V n Foo
和
Bar n
是
Int
.但我对此不确定。