我有一个新类型X
,它基本上是一个Ints列表。我使用ClassyPrelude而不是标准的Prelude,并希望派生IsSequence类。这使得有必要派生出许多其他类。
语言扩展名GeneralizedNewtypeDeriving应该允许这个(这里与DerivingStrategies扩展一起使用)。我想要:
newtype X = X [Int] deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
完整档案:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}
module Test where
import ClassyPrelude
newtype X = X [Int] deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
type instance Element X = Int
(所有其他语言扩展似乎都很重要)
但是,这会为MonoTraversable
和IsSequence
生成大量错误消息:
/path/to/file/Test.hs:13:48: error:
• Couldn't match representation of type ‘m [Int]’
with that of ‘m X’
arising from the coercion of the method ‘omapM’
from type ‘forall (m :: * -> *).
Applicative m =>
(Element [Int] -> m (Element [Int])) -> [Int] -> m [Int]’
to type ‘forall (m :: * -> *).
Applicative m =>
(Element X -> m (Element X)) -> X -> m X’
NB: We cannot know what roles the parameters to ‘m’ have;
we must assume that the role is nominal
• When deriving the instance for (MonoTraversable X)
|
13 | deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
| ^^^^^^^^^^^^^^^
/path/to/file/Test.hs:13:48: error:
• Couldn't match representation of type ‘f [Int]’
with that of ‘f X’
arising from the coercion of the method ‘otraverse’
from type ‘forall (f :: * -> *).
Applicative f =>
(Element [Int] -> f (Element [Int])) -> [Int] -> f [Int]’
to type ‘forall (f :: * -> *).
Applicative f =>
(Element X -> f (Element X)) -> X -> f X’
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
• When deriving the instance for (MonoTraversable X)
|
13 | deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
| ^^^^^^^^^^^^^^^
/path/to/file/Test.hs:13:115: error:
• Couldn't match type ‘[Int]’ with ‘X’
arising from the coercion of the method ‘initMay’
from type ‘IsSequence [Int] => [Int] -> Maybe [Int]’
to type ‘IsSequence X => X -> Maybe X’
• When deriving the instance for (IsSequence X)
|
13 | deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
| ^^^^^^^^^^
/path/to/file/Test.hs:13:115: error:
• Couldn't match representation of type ‘m [Int]’
with that of ‘m X’
arising from the coercion of the method ‘replicateM’
from type ‘forall (m :: * -> *).
Monad m =>
Index [Int] -> m (Element [Int]) -> m [Int]’
to type ‘forall (m :: * -> *).
Monad m =>
Index X -> m (Element X) -> m X’
NB: We cannot know what roles the parameters to ‘m’ have;
we must assume that the role is nominal
• When deriving the instance for (IsSequence X)
|
13 | deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
| ^^^^^^^^^^
/path/to/file/Test.hs:13:115: error:
• Couldn't match representation of type ‘m [Int]’
with that of ‘m X’
arising from the coercion of the method ‘filterM’
from type ‘forall (m :: * -> *).
Monad m =>
(Element [Int] -> m Bool) -> [Int] -> m [Int]’
to type ‘forall (m :: * -> *).
Monad m =>
(Element X -> m Bool) -> X -> m X’
NB: We cannot know what roles the parameters to ‘m’ have;
we must assume that the role is nominal
• When deriving the instance for (IsSequence X)
|
13 | deriving newtype (MonoFunctor, MonoFoldable, MonoTraversable, Monoid, GrowingAppend, SemiSequence, MonoPointed, IsSequence)
|
我无法阅读(也许它与默认签名有关?,不知道......)。从derinding子句中省略2个类会使代码编译。
问题:在这种情况下如何派生IsSequence?
由于多种原因,我的用例不能使用类型别名,但我想使用这些类提供的功能。如果无法推导,则有必要自己实现类方法。