Haskell (newtype Mu f=InF{outp::f(Mu f)})的函子实例
这把我难住了。如何为Haskell (newtype Mu f=InF{outp::f(Mu f)})的函子实例,haskell,functor,Haskell,Functor,这把我难住了。如何为newtype Mu f=InF{outF::f(Mu f)}编写一个函子实例?您不能。为了为某些c定义实例函子c,c必须是*->*类型。所以在你的例子中,Mu应该是那种类型的,这意味着它的参数f必须是*类型的。但显然情况并非如此,因为您正在将f应用于其他对象(到muf) 更简单地说,如果Mu是一个函子,您可以对Mu f类型的值使用fmap来表示任何f。但这将允许您将类型参数更改为任何其他类型,例如,通过将函数fmap(const(0::Int))应用于任何Mu f值,它将必
newtype Mu f=InF{outF::f(Mu f)}
编写一个函子实例?您不能。为了为某些c
定义实例函子c
,c
必须是*->*
类型。所以在你的例子中,Mu
应该是那种类型的,这意味着它的参数f
必须是*
类型的。但显然情况并非如此,因为您正在将f
应用于其他对象(到muf
)
更简单地说,如果
Mu
是一个函子,您可以对Mu f
类型的值使用fmap
来表示任何f
。但这将允许您将类型参数更改为任何其他类型,例如,通过将函数fmap(const(0::Int))
应用于任何Mu f
值,它将必须返回Mu Int
值。但是您不能形成这样一个值,因为该值的outF
将具有类型Int(Mu Int)
,这是没有意义的。redneb很好地解释了为什么Mu
不能是常规的Functor
但是您可以为Mu
实现一种类似于Functor的映射操作
{-# 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
虽然我不确定它对你的情况有多大用处。:) 稍微修改一下
Mu
,与user2297560不同,就足以为Mu提供一个函子实例:
-- 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)
这个公式来自Patricia和Neil的论文。我将添加显式的种类签名
Mu:(*->*)->*
,以强调它不是函子所需要的(*->*
),因此我们得到一个种类错误。如果你这样做新类型Mu f a=InF{outF::f(Mu f a)}
实例函子f=>函子(Mu f)
是可能的。不过,这只是免费的
,没有纯的
构造函数。请检查围绕这个问题的思考。感兴趣的人,这是第16章的练习。Haskell编程的函子从First Principles.IOWMu
是从类型构造函数类*->*
(其态射是所有x.f x->Gx
的自然变换)到Haskell类型和函数类的函子