这个使用 RankNTypes 的仿函数的名称是什么?

What is the name of this functor that uses RankNTypes?

在玩 objective 包时,我注意到以下类型很有趣 属性。

> {-# LANGUAGE RankNTypes #-}
> data N f r = N { unN :: forall x. f x -> (x, r) }

它是一个函子。

> instance Functor (N f) where
>    fmap f (N nat) = N $ fmap (fmap f) nat
>          -- or,   = N $ \fx -> let { (x,a) = nat fx } in (x, f a)

google/hoogle几个小时后,我放弃了寻找任何 包含此类型的现有模块。 这是什么类型的?如果众所周知,叫什么名字?这是有用的还是因为没用而被忽略?

这不是我 100% 的原创,因为 N 是从 objective 包中找到的对象派生的。

> data Object f g = Object {
>     runObject :: forall x. f x -> g (x, Object f g)
>   }

N f 是一个 Functor,当应用 Fix 时它产生 Object f Identity


以下是关于这种类型的事实以及我认为它很有趣的原因。

N 将 Reader 转换为 Writer,反之亦然。 (这里我用(=)符号表示类型之间的同构)

N ((->) e) r
 = forall x. (e -> x) -> (x, r)
 = (e, r)

N ((,) d) r
 = forall x. (d, x) -> (x, r)
 = d -> r

N 将 Store comonad 转换为 State monad,但反之则不然。

> data Store s a = Store s (s -> a)
> type State s a = s -> (s, a)

N (Store s) r
 = forall x. (s, (s -> x)) -> (x, r)
 = forall x. s -> (s -> x) -> (x, r)
 = s -> (s, r)
 = State s r

N (State s) r
 = forall x. (s -> (s, x)) -> (x, r)
 = forall x. (s -> s, s -> x) -> (x, r)
 = forall x. (s -> s) -> (s -> x) -> (x, r)
 = (s -> s) -> (s, r)  -- ???

N 不能接受 Maybe。

N Maybe r
 = forall x. Maybe x -> (x, r)
 = forall x. (() -> (x, r), x -> (x, r))
 = Void     -- because (() -> (x, r)) can't be implemented

以下功能可能很有趣。我做不到它的倒数。

> data Cofree f a = Cofree a (f (Cofree f a))
> data Free f a = Pure a | Wrap (f (Free f a))

> unfree :: Free (N f) r -> N (Cofree f) r
> unfree (Pure r) = N $ \(Cofree a _) -> (a, r)
> unfree (Wrap n_f) = N $
>   \(Cofree _ f) -> let (cofree', free') = unN n_f f
>                    in unN (unfree free') cofree'

全部 post 识字 Haskell (.lhs).

我称它为 "handler" 函子。在我发布 objective 之前,Object 曾经是使用处理函数定义的。

是的,这个仿函数很有趣——Cofree (Handler f) 有一个 public getter 而 Free (Handler f) 是一个 mortal object。也许我应该发布处理函数...

虽然已经回答了,但是我自己找到了另一个问题的答案。

类型 N 是类型 class Pairing 的值级别表示,将在以下文章中进行描述。

Free for DSLs, cofree for interpreters

Cofree Comonads and the Expression Problem (配对在这里称为双)

配对和N是一回事

Pairing的定义是这样的

> class Pairing f g where
>   pair :: (a -> b -> c) -> f a -> g b -> c

fN f 正在配对。

> instance Pairing f (N f) where
>   pair k fa nb = uncurry k $ unN nb fa

N可以用Pairing来表示

> data Counterpart f r = forall g. Pairing f g => Counterpart (g r)
>
> iso1 :: N f r -> Counterpart f r
> iso1 = Counterpart
>
> iso2 :: Counterpart f r -> N f r
> iso2 (Counterpart gr) = N $ \fx -> pair (,) fx gr

有一个 Free-vs-Cofree 实例,对应于我的 unfree。 文章中还定义了其他有趣的实例。

> instance Pairing f g => Pairing (Free f) (Cofree g) where
>   pair = undefined -- see link above

将配对扩展到 PairingM 到对象

前一篇文章goes to扩展 Pairing 以在 Monad m 中进行计算。

> class PairingM f g m | f -> g, g -> f where
>   pairM :: (a -> b -> m r) -> f a -> g b -> m r

如果我们将PairingM改写成类似N的形式,我们又得到了Object

> -- Monad m => HandlerM' f m r ~ HandlerM f m r
> data HandlerM' f m r = forall g. PairingM f g m => HandlerM' (g r)
> data HandlerM f m r = HandleM { runHandlerM :: forall x. f x -> m (x, r) }
>
> -- Fix (HandlerM f m) ~ Object f m
> -- Free (HandlerM f m) ~ (mortal Object from f to m)