(newtype Mu f = InF {outF :: f(Mu f)})的Functor实例

时间:2016-09-29 12:20:41

标签: haskell functor

这让我很难过。如何为newtype Mu f = InF {outF :: f (Mu f)}

编写Functor实例

3 个答案:

答案 0 :(得分:7)

你做不到。为了为某些Functor c定义实例cc必须属于* -> *种类。因此,在您的情况下,Mu应该属于那种类型,这意味着其参数f必须属于*类型。但显然情况并非如此,因为您正在将f应用于其他内容(Mu f)。

更简单地说,如果Mu是一个仿函数,则可以对任何fmap类型Mu f的值使用f。但这可以让您将类型参数更改为任何其他类型,例如,通过将函数fmap (const (0 :: Int))应用于任何Mu f值,它必须返回Mu Int值。但是你不能形成这样的值,因为该值的outF将具有无效的类型Int (Mu Int)

答案 1 :(得分:4)

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

虽然我不确定你的情况会有多大用处。 :)

答案 2 :(得分:0)

Mu进行轻微的重新措辞,与user2297560不同,足以接受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)

这个表述来自Patricia和Neil的论文Haskell Programming with Nested Types: A Principled Approach