类型类的函子和应用程序(* - > *) - > * [英] Functors and Applicatives for types of kind (* -> *) -> *

查看:126
本文介绍了类型类的函子和应用程序(* - > *) - > *的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个情况,我的代码会受益于使用 Functor Applicative 类似抽象,但对于类型的类型(* - > *) - > * 。使用 RankNTypes 来定义一个更高级的仿函数,就像这样

  class HFunctor f其中
hfmap ::(forall x。ax - > bx) - > f a - > fb

但是更高版本的 Applicative 有点棘手。这是我能想到的最好的:

  class HFunctor f =>其中
hpure ::(forall x。a x) - > f a
(< **>):: f(a: - > b) - > f a - > f b

newtype(: - >)a b x = HFunc(a x - > b x)

infixr 5: - >

我们需要: - > wrapper键入以便具有 * - >类型的函数。 * ,但这并不能让我们很好地链接函数应用程序,就像我们可以用< $> < ; *> 适用于正常的应用程序。我可以使用helper来管理,比如

  liftHA2 :: HApplicative f => (全部×a× - > b× - > c×) - > f a  - > f b  - > f c 
liftHA2 f fa fb = hpure(fun2 f)< **> fa **> fb其中
fun2 = HFunc。 (HFunc。)

但是,如果有一种通用的方法来提升



 data示例f =示例(f Int)(f String)

实例HFunctor示例其中
hfmap f(示例为)=示例(fi)(fs)

实例其中
hpure a =示例aa
的适用示例示例(HFunc fi)(HFunc fs)**<示例是=示例(fi i)(fs s)

e ::示例[]
e =示例[1,2,3] [foo,bar]

e':: Example((,)Int)
e'= hfmap(length&& head)e - 例子(3,1)(2,foo)

e''::示例[]
e''= liftHA2(++)ee - 示例[1,2,3,1,2,3] [foo ,bar,foo,bar]

所以,我的问题是:上面的类型类被调用,它们是否已经被某些库提供了hackage?通过Google搜索,我在 Functor2 html / Control-Functor.html> linear-maps HFunctor in 多REC ,但都不是我所需要的。

另外,有没有方法可以编写适用的 : - >> wrapper或其他一些方法可以让函数提升更容易吗?

我倾向于认为的HFunctor是(* - > *) - > * - > * - 即仿函子的合法仿函数。这与你所想的不同。



下面是如何定义它,以及应用程序的monoidal版本。 p>

 输入Nat fg = forall a。 f a  - > g a 

class HFunctor(f ::(* - > *) - > * - > *)其中
hfmap ::(Nat g h) - > Nat(f g)(f h)

data Prod f g a = Prod(f a)(g a)

class HFunctor f =>有效的f,其中
hpure :: Nat g(fg)
htensor :: Nat(Prod(fg)(fh))(f(Prod gh))



我会稍后尝试更新一些关于这是什么以及如何使用它的想法。



这不完全是你要求的,我意识到,但我的灵感来自你的帖子尝试。



我对你的具体用例感兴趣。

针对你的两个具体问题A)你描述过的HFunctor在以前的各种场合都有描述,我特别认为是Gibbons,但我不知道它是否包装好。我当然没有见过这个应用程序。 B)我认为你被封装了,因为我们不能部分应用类型同义词。


I ran into a situation where my code would benefit from using Functor and Applicative -like abstractions, but for types of kind (* -> *) -> *. Defining a higher-kinded functor can be done with RankNTypes like this

class HFunctor f where
    hfmap :: (forall x. a x -> b x) -> f a -> f b

But the higher kind version of Applicative is a bit trickier. This is the best I could come up with:

class HFunctor f => HApplicative f where
    hpure  :: (forall x. a x) -> f a
    (<**>) :: f (a :-> b) -> f a -> f b

newtype (:->) a b x = HFunc (a x -> b x)

infixr 5 :->

We need the :-> wrapper type in order to have functions with the kind * -> *, but this doesn't let us nicely chain function application like we can with <$> and <*> for normal Applicatives. I can manage with helper such as

liftHA2 :: HApplicative f => (forall x. a x -> b x -> c x) -> f a -> f b -> f c
liftHA2 f fa fb = hpure (fun2 f) <**> fa <**> fb where
    fun2 = HFunc . (HFunc .)

But it would be nice to have a general way to "lift" functions of any arity.

Some simple examples how the above instances can be used:

data Example f = Example (f Int) (f String)

instance HFunctor Example where
    hfmap f (Example i s) = Example (f i) (f s)

instance HApplicative Example where
    hpure a = Example a a
    Example (HFunc fi) (HFunc fs) <**> Example i s = Example (fi i) (fs s)

e :: Example []
e = Example [1,2,3] ["foo", "bar"]

e' :: Example ((,) Int)
e' = hfmap (length &&& head) e  -- Example (3,1) (2, "foo")

e'' :: Example []
e'' = liftHA2 (++) e e  -- Example [1,2,3,1,2,3] ["foo", "bar", "foo", "bar"]

So, my question is: what are the above typeclasses called and are they already provided by some library in hackage? By googling I came up with Functor2 in linear-maps and HFunctorin multi-rec but neither does exactly what I need.

Also, is there some way to write HApplicative without the :-> wrapper or some other way to make function lifting easier?

解决方案

The HFunctor I tend to think of is (* -> *) -> * -> * -- i.e. a legitimate functor on functors. This has different characteristics than the one you're thinking of.

Here's how to define it, as well as the "monoidal" version of an applicative on it.

type Nat f g = forall a. f a -> g a

class HFunctor (f :: (* -> *) -> * -> *) where
    hfmap :: (Nat g h) -> Nat (f g) (f h)

data Prod f g a = Prod (f a) (g a)

class HFunctor f => HApplicative f where
    hpure  :: Nat g (f g)
    htensor :: Nat (Prod (f g) (f h)) (f (Prod g h))

I'll try to update later with some ideas about what this is and how to use it.

This isn't exactly what you're asking for, I realize, but I was inspired to try it out by your post.

I'd be interested in your specific use case as well.

To your two specific questions A) The HFunctor you describe has been described before on various occasions, I think by Gibbons in particular, but I don't know of it packaged up. I certainly haven't seen the Applicative before. B) I think you're stuck with the wrapper because we can't partially apply type synonyms.

这篇关于类型类的函子和应用程序(* - &gt; *) - &gt; *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆