我有這種類型的同義詞:重新定義實例要麼與特定類型
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。 –