【发布时间】:2020-09-23 17:38:40
【问题描述】:
我有以下类型,基于论文Coroutining 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和Coerrcible (Hyper c a) (Hyper b a),后者需要Coercible (Hyper a b) (Hyper a c),但它进入了一个无限循环。
知道我会用什么注释来解决这个问题,如果有的话?还是我应该硬着头皮使用unsafeCoerce?
【问题讨论】:
-
哇,这听起来确实像 GHC 错误!请举报!
-
嗯...实际上,这很棘手。不,可能没有解决方法。
-
我猜你不想要
(#.) _ = rmap coerce,对吧? -
@chi,这根本没用,因为它不是免费的。
-
@chi,我应该更具体一些。编写该定义根本没有用,因为这是默认定义所做的。
标签: haskell coercion profunctor