试图将一个包裹类型的家庭变成一个Functor

以下是一个简单的例子,其中身份证明函数运作良好:

newtype R a = R a

instance Functor R where
    fmap f (R a) = R $ f a

但如果我添加一个中间类型的家庭,事情会变得糟糕:

data IntT
data a :-> b

type family   Sem a         :: *
type instance Sem IntT      = Int
type instance Sem (a :-> b) = Sem a -> Sem b

newtype S a = S (Sem a)

现在我不能让S变成一个Functor。 我可以很容易地定义一类新的类似Functor的东西,但是我还需要一类类似Applicative的和Monad类的东西,这似乎是一条不愉快的道路。 尤其如

smap f (S a) = S $ f a

实际上有我想要的类型,即smap :: (Sem a -> Sem b) -> S a -> S b 。 但是,当然,这不是一个Functor的类型。 (当“相同”代码有两种不同的,不兼容的类型时,你难道不喜欢它吗?)

我已经探索Data.Category.Functor以及Generics.Pointless.Functors,但似乎也无法解决我的问题。 PointlessTypeFamilies似乎有更好的想法,但我仍然不确定如何获得足够类似Functor的东西。

虽然smap的代码与Rfmap的代码相同,但是发生的事情略有不同。 在某种程度上,如果我从SemS发生了自然变化,那么我应该能够提升它以获得smap 。 那时候,我觉得我不妨在这里问一下,这可以为我节省很多麻烦!


当我遇到像这样的情况时,我通常会切换到如下所示的状态:

data S b = forall a. S (a -> b) (Sem a)

它可以很容易地变成一个守法的Functor

instance Functor S where
  fmap f (S g s) = S (f . g) s

或者我转向Coyoneda来为我打包这种行为。

链接地址: http://www.djcxy.com/p/11431.html

上一篇: Trying to make a wrapped type family into a something Functor

下一篇: IDENTITY type field in SQL Server database