You can't. In order to define an instance Functor c for some c , c must be of the kind * -> * . So in your case, Mu should have been of that kind, which means that its argument f must have been of the kind * . But clearly this is not the case, as you are applying f to something else (to Mu f ). To put it more simply, if Mu was a functor, you could use fmap on values of type Mu f for any f . But this would have allowed you to change the type parameter to any other type, e.g., by applying the function fmap (const (0 :: Int)) to any Mu f value, it would have to return a Mu Int value. But you can not form such a value because the outF of that value would have had type Int (Mu Int) which does not make sense.
4条答案
按热度按时间83qze16e1#
You can't. In order to define an instance
Functor c
for somec
,c
must be of the kind* -> *
. So in your case,Mu
should have been of that kind, which means that its argumentf
must have been of the kind*
. But clearly this is not the case, as you are applyingf
to something else (toMu f
).To put it more simply, if
Mu
was a functor, you could usefmap
on values of typeMu f
for anyf
. But this would have allowed you to change the type parameter to any other type, e.g., by applying the functionfmap (const (0 :: Int))
to anyMu f
value, it would have to return aMu Int
value. But you can not form such a value because theoutF
of that value would have had typeInt (Mu Int)
which does not make sense.carvr3hs2#
redneb很好地解释了为什么
Mu
不能是正则Functor
,但是可以为Mu
实现一种类似于函子的Map操作,如下所示虽然我不确定它对你的情况有多有用。:)
ymdaylpp3#
与user2297560的不同,对
Mu
进行轻微的重新措辞,就足以允许Mu的函子示例:这个公式来自Patricia和Neil的论文Haskell Programming with Nested Types: A Principled Approach。
euoag5mw4#
正如redneb所描述的,一个函子示例必须有
* -> *
类型,这就禁止了Mu
是一个函子,假设它的参数f
被应用于f (Mu f)
中的一个参数。这里有一个涉及到的各种类型的分类。
首先,要创建的新类型在应用了所有参数之后必须具有kind
*
。因此:Mu f
必须具有*
种类第二,
Mu f
被设置为等于的东西也必须具有相同的类型。也就是说,InF { outF :: f (Mu f) }
必须具有*
种类第三,
outF
是一个函数,因此必须返回一个完全实现的类型,无论是参数化的还是具体的,即*
类型。f (Mu f)
是它的返回类型。因此f (Mu f)
必须具有*
种类最后,
f
是一个应用类,因为它出现在f (Mu f)
中,换句话说,它有类f_argument_kind -> f_result_kind
,它有类f_argument_kind
和类f_result_kind
,而且f (Mu f)
告诉我们f_argument_kind
和f_result_kind
的类,也就是说,f_argument_kind
与Mu f
的种类(*
)匹配,并且f_result_kind
与f (Mu f)
的种类(*
)匹配。f
的种类为* -> *
。将其与已知类型的
Mu f
(*
)结合,我们得到类型构造函数的类型。Mu
的种类为(* -> *) -> *
。