我有以下类型,它基于论文Cooutining folds with hyperfunctions:
newtype Hyper a b = Hyper { invoke :: Hyper b a -> b }
它的第一个参数是逆变的,第二个参数是协变的,所以它是一个 profunctor:
instance Profunctor Hyper where
lmap f = go where
go (Hyper h) = Hyper $ \(Hyper k) -> h $ Hyper $ f . k . go
rmap g = go where
go (Hyper h) = Hyper $ \(Hyper k) -> g $ h $ Hyper $ k . go
dimap f g = go where
go (Hyper h) = Hyper $ \(Hyper k) -> g $ h $ Hyper $ f . k . go
我还想实现(可能不安全的)强制运算符:
-- (#.) :: Coercible c b => q b c -> Hyper a b -> Hyper a c
(#.) _ = coerce
-- (.#) :: Coercible b a => Hyper b c -> q a b -> Hyper a c
(.#) = const . coerce
但是,当我这样做时,我收到以下错误消息:
• Reduction stack overflow; size = 201
When simplifying the following type:
Coercible (Hyper a b) (Hyper a c)
Use -freduction-depth=0 to disable this check
(any upper bound you could choose might fail unpredictably with
minor updates to GHC, so disabling the check is recommended if
you're sure that type checking should terminate)
• In the expression: coerce
In an equation for ‘#.’: (#.) _ = coerce
我猜它正在尝试验证Coercible (Hyper a b) (Hyper a c)
,这需要Coercible b c
and Coerrcible (Hyper c a) (Hyper b a)
,而后者需要Coercible (Hyper a b) (Hyper a c)
,但它进入了一个无限循环。
知道我会用什么注释来解决这个问题,如果有的话?还是我应该硬着头皮使用unsafeCoerce
?