[英]Functors and Applicatives for types of kind (* -> *) -> *
I ran into a situation where my code would benefit from using Functor
and Applicative
-like abstractions, but for types of kind (* -> *) -> *
. 我遇到了一种情况,我的代码将从使用
Functor
和类似Applicative
的抽象中受益,但对于类型(* -> *) -> *
。 Defining a higher-kinded functor can be done with RankNTypes
like this 定义更高级的仿函数可以使用这样的
RankNTypes
来完成
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. 但是更高版本的
Applicative
有点棘手。 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. 我们需要
:->
包装器类型,以便具有类型* -> *
函数,但这不能让我们很好地链接函数应用程序,就像我们可以使用<$>
和<*>
使用普通的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. 但是有一个通用的方法可以“解除”任何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? 所以,我的问题是:上面提到的类型类是什么,它们是否已经被一些库中的hackage提供了? By googling I came up with
Functor2
in linear-maps
and HFunctor
in multi-rec
but neither does exactly what I need. 谷歌搜索,我想出了
Functor2
的linear-maps
和HFunctor
在multi-rec
但同样没有正是我需要的。
Also, is there some way to write HApplicative
without the :->
wrapper or some other way to make function lifting easier? 另外,是否有一些方法可以编写
HApplicative
而不使用:->
包装器或其他一些方法来使函数提升更容易?
The HFunctor I tend to think of is (* -> *) -> * -> *
-- ie a legitimate functor on functors. 我倾向于认为的HFunctor是
(* -> *) -> * -> *
- 即仿函数上的合法函子。 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. 以下是如何定义它,以及应用程序的“monoidal”版本。
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. 关于你的两个具体问题A)你所描述的HFunctor之前已经在不同场合进行了描述,我特别想到Gibbons,但我不知道它是否打包过。 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.
B)我认为你坚持使用包装器,因为我们不能部分应用类型同义词。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.