如何製作(a, a)
a Functor
而不訴諸於newtype
?製作(a,a)分散器
基本上我希望它是這樣工作的:
instance Functor (a, a) where
fmap f (x, y) = (f x, f y)
當然,這並不表示它一個合法的方式,而是:
Kind mis-match
The first argument of `Functor' should have kind `* -> *',
but `(a, a)' has kind `*'
In the instance declaration for `Functor (a, a)'
我真正想要的是像一個類型級功能這個:\a -> (a, a)
(語法無效)。那麼可能是一個類型別名?
type V2 a = (a, a)
instance Functor V2 where
fmap f (x, y) = (f x, f y)
我會認爲這會工作,但事實並非如此。首先,我得到這個投訴:
Illegal instance declaration for `Functor V2'
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Functor V2'
如果我照做,並添加TypeSynonymInstances
擴展,我得到一個新的錯誤:
Type synonym `V2' should have 1 argument, but has been given 0
In the instance declaration for `Functor V2'
嗯,真不錯,這就是問題所在! V2
有種* -> *
,這是Functor
實例所要求的。好吧,好吧,我可以用一個newtype
這樣的:
newtype V2 a = V2 (a, a)
instance Functor V2 where
fmap f (V2 (x, y)) = V2 (f x, f y)
但現在我得撒V2
小號寬鬆在我的代碼,而不是隻能夠處理簡單的元組,哪一種違背了點使其成爲Functor
;在那一點上,我不妨做我自己的功能vmap :: (a -> b) -> (a, a) -> (b, b)
。
那麼有沒有什麼辦法可以做到這一點,即沒有newtype
?
什麼時候你想讓元組變成這樣的Functor?在我看來,如果你需要uber-Functor的權力來操作特殊的元組,你應該首先使用自定義的數據結構,而不是元組。你操縱的元組代表什麼? – 2011-01-27 05:17:55
@丹我並不需要「超級強大的功能」,它只是輕度方便,似乎應該是可能的,如果不是我很好奇爲什麼。 – 2011-01-27 05:34:47
@pelotom我同意這看起來應該是可能的,儘管看起來不是這樣。我只是想,我會花一點時間來使用我的soapbox,並宣傳爲你的問題量身定製一個表達式結構的好處,而不是重載元組。 – 2011-01-27 05:42:02