这把我难倒了。如何为newtype Mu f = InF {outF :: f (Mu f)}编写函数器实例
发布于 2016-09-29 20:25:58
不能。为了定义某个c的实例Functor c,c必须是* -> *类型的。所以在你的例子中,Mu应该是这种类型的,这意味着它的参数f一定是*类型的。但显然情况并非如此,因为您正在对其他东西( Mu f)应用f。
更简单地说,如果Mu是一个函数器,那么您可以对任何f的Mu f类型的值使用fmap。但这将允许您将类型参数更改为任何其他类型,例如,通过将函数fmap (const (0 :: Int))应用于任何Mu f值,它将必须返回Mu Int值。但是您不能形成这样的值,因为该值的outF将具有Int (Mu Int)类型,这是没有意义的。
发布于 2016-09-29 21:56:15
redneb很好地解释了为什么Mu不能是常规的Functor,但是您可以为Mu实现一种类似函数式的映射操作,如下所示
{-# LANGUAGE RankNTypes #-}
newtype Mu f = InF {outF :: f (Mu f)}
mumap :: Functor f => (forall a. f a -> g a) -> Mu f -> Mu g
mumap f (InF m) = InF $ f $ fmap (mumap f) m尽管我不确定它对你的情况有多大用处。:)
发布于 2018-02-06 11:18:42
与user2297560的不同,对Mu稍作修改,就足以为Mu引入一个Functor实例:
-- Natural transformations
type g ~> h = forall a. g a -> h a
class HFunctor f where
ffmap :: Functor g => (a -> b) -> f g a -> f g b
hfmap :: (Functor g, Functor h) => (g ~> h) -> (f g ~> f h)
newtype Mu f a = In { unIn :: f (Mu f) a }
instance HFunctor f => Functor (Mu f) where
fmap f (In r) = In (ffmap f r)这个公式来自帕特里夏和尼尔的论文Haskell Programming with Nested Types: A Principled Approach。
https://stackoverflow.com/questions/39770191
复制相似问题