我有这种类型的同义词:重新定义实例要么与特定类型
type ParseResult a = Either [CompilerError] (a, [CompilerWarning])
凡CompilerError
和CompilerWarning
是数据类型。
现在我知道,无论是有实例Functor
和Applicative
但Functor
实例上的元组(a,[CompilerWarning])
适用fmap
,我要重新定义实例对于这种类型的同义词,这样fmap
适用于a
不整元组,同去为Applicative
。
如果我使用newtype
,我将不得不把ParseResult
放在各处,我已经写了很多代码。
我知道我需要TypeSynonymInstances
但我this问题面临着同样的问题,从我想我需要定义我喜欢的类型同义词这样的问题:
type ParseResult = ...
我需要填写...
,我不知道如何使* -> *
与Either
和tuple
,我试图Either [CompilerError] ((,) [CompilerWarning])
,但这有两个问题:第一个CompilerWarning
是第一个元素,我需要它是第二个(所以我没有改变很多代码),第二我得到这个消息:
•期待一个更参数 '(,)[CompilerWarning]' 预期一个类型,但 '(,)[CompilerWarning]' 具有一种 '* - > *' •在任一“的第二个参数”,即 '(,)[CompilerWarning]' 在类型 '为[CompilerError]((,)[CompilerWarning])' 在类型声明 'ParseResult'
什么是最好的,最昂贵的解决这个问题?
制作功能'ParseResult'一个'newtype',而不是一个类型别名。这样,你可以在它上定义自己的实例,而不会与已经为'Either'定义的实例冲突。 –
如果您可以将数据类型更改为'[CompileError]([CompilerWarning],a)',您可以简单地使用'fmap'两次:'(fmap。fmap)(+1)(Right([],1)) '评估为'正确([],2)'。 – chepner
我真的不明白TypeSynonymInstances如何引起如此多的混淆。它所做的一切就是用实例扩展替换实例头中的类型同义词。你可以自己做,所以你永远不需要TypeSynonymInstances。 –