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

时间:2016-04-29 03:23:25

标签: haskell functor higher-rank-types

在围绕objective包玩游戏时,我注意到以下类型具有有趣的属性。

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

这是一个Functor。

> 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源自目标包中的Object。

> 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,但inverse不为真。

> 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不能采取可能。

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'

整篇文章都是有文化的Haskell(.lhs)。

2 个答案:

答案 0 :(得分:2)

我称之为"处理程序"仿函数。在我发布目标之前,曾经使用处理程序仿函数定义Object

是的,这个仿函数很有趣 - Cofree (Handler f)有一个公共吸气者,Free (Handler f)mortal object。也许我应该运送处理程序函子......

答案 1 :(得分:1)

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

类型N是类型类Pairing的值级表示形式,在以下文章中有所描述。

Free for DSLs, cofree for interpreters

Cofree Comonads and the Expression Problem (Paring在这里称为Dual)

配对和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可以用配对来表示。

> 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到Object

前篇文章goes to扩展配对以在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)