我有一个新类型来代表 Hughes 的列表(即列表构造):
newtype Hughes a = Hughes {unHughes :: [a] -> [a]}
有一些功能可以处理它:
mkHughes :: [a] -> Hughes a
mkHughes = Hughes . (++)
runHughes :: Hughes a -> [a]
runHughes h = unHughes h []
该Monoid
实例与上述功能一样简单:
instance Monoid (Hughes a) where
mempty = Hughes id
mappend (Hughes f) (Hughes g) = Hughes (f . g)
...但是当我到达Functor
andApplicative
实例时,麻烦就出现了。到目前为止,这是我想出的:
instance Functor Hughes where
fmap f (Hughes h) = Hughes $ unsafeCoerce $ fmap f . h
instance Applicative Hughes where
pure = Hughes . (:)
(<*>) (Hughes f) (Hughes v) = Hughes $ unsafeCoerce $
(<*>) <$> f <*> unsafeCoerce v
我的问题是我不喜欢使用unsafeCoerce
. 有没有办法在Functor
不使用实例的情况下设计实例,还是不可避免?
此外,我将如何实现Monad
此数据类型的实例?
编辑:与DList
包中不同,我想保持性能改进,即不评估[a] -> [a]
但映射它。