在这个答案中,我当场编造了一些看起来有点像“高阶Traversable
”的东西:就像Traversable
但对于从 Hask 到 Hask 的 endofunctors 类别的函子。
{-# LANGUAGE RankNTypes #-}
import Data.Functor.Compose
import Data.Functor.Identity
class HFunctor t where
hmap :: (forall x. f x -> g x) -> t f -> t g
class HFunctor t => HTraversable t where
htraverse :: Applicative g => (forall x. f x -> g x) -> t f -> g (t Identity)
htraverse eta = hsequence . hmap eta
hsequence :: Applicative f => t f -> f (t Identity)
hsequence = htraverse id
我创建了HFunctor
一个超类,HTraversable
因为它看起来是正确的,但是当我坐下来写作时,hmapDefault
我被卡住了。
hmapDefault :: HTraversable t => (forall x. f x -> g x) -> t f -> t g
hmapDefault eta = runIdentity . htraverse (Identity . eta)
-- • Couldn't match type ‘x’ with ‘g x’
-- Expected type: f x -> Identity x
-- Actual type: f x -> Identity (g x)
Identity . eta
有一个 type forall y. f y -> Identity (g y)
,所以当我将它传递给htraverse
g
unifies withIdentity
并且x
必须与两者统一时y
,g y
它会失败,因为遍历函数不是自然转换。
我尝试使用以下方法对其进行修补Compose
:
hmapDefault :: HTraversable t => (forall x. f x -> g x) -> t f -> t g
hmapDefault eta = runIdentity . getCompose . htraverse (Compose . Identity . eta)
现在Compose . Identity . eta
是一个自然的转变,但你不能htraverse
接受它,因为你不知道Applicative g
。即使你能做到这一点,runIdentity
调用也会返回g (t Identity)
,你将无法将g
back 放入t
.
然后我意识到 myhtraverse
并不是真的类似于普通的 old traverse
。的遍历函数traverse
将新值放入Applicative
效果中,使类型表达式更大。所以htraverse
应该看起来像这样:
class HFunctor t => HTraversable t where
htraverse :: Applicative a => (forall x. f x -> a (g x)) -> t f -> a (t g)
很有希望这个定义看起来更像Traversable
,并且hmapDefault
顺利进行,
hmapDefault :: HTraversable t => (forall x. f x -> g x) -> t f -> t g
hmapDefault eta = runIdentity . htraverse (Identity . eta)
但我正在努力为sequenceA
. 我试过了
hsequence :: (HTraversable t, Applicative f) => t f -> f (t Identity)
hsequence = htraverse (fmap Identity)
但我想不出一种实现htraverse
方式hsequence
。和以前一样,f
不是自然的转变。
htraverse f = hsequence . hmap f
-- • Couldn't match type ‘x’ with ‘g x’
-- Expected type: f x -> a x
-- Actual type: f x -> a (g x)
我怀疑我的hsequence
类型签名错误。问题是Applicative
- 我需要一直到索引单子吗?Functor
“从类别到 Hask的可遍历函子”的类应该是什么样的?这样的事情还存在吗?