Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#10156 closed feature request (invalid)

Unable to coerce with flipped Coercible context

Reported by: ekmett Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 7.8.4
Keywords: Cc: glguy
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: typecheck/should_compile/T10156
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

coerce' :: Coercible a b => b -> a
coerce' = coerce

doesn't compile, forcing workarounds like:

coerce' :: forall a b. Coercible a b => b -> a
coerce' = coerce (id :: a -> a)

This arises in practice in several places in the profunctors package and lens.

https://github.com/ekmett/profunctors/blob/1c3508e5274a0ed03765c569596a8fda8817ed56/src/Data/Profunctor/Unsafe.hs#L188

http://hackage.haskell.org/package/lens-4.8/docs/src/Control-Lens-Internal-Coerce.html#coerce%27

Ideally we'd be able to retire coerce' entirely and just use coerce in those contexts.

The tricky part is of course avoiding infinite loops once you add symmetry.

Change History (8)

comment:1 Changed 3 years ago by glguy

Cc: glguy added

comment:2 Changed 3 years ago by goldfire

I happen to be playing in this area this minute. Will try to fix this. But not for 7.10.

comment:3 Changed 3 years ago by goldfire

Status: newinfoneeded

I can't reproduce this with RC2. I wouldn't expect it to work in 7.8, but it should work in 7.10. (When I saw the ticket, I was quite surprised it didn't, as I thought the new solver handled symmetry!)

comment:4 Changed 3 years ago by glguy

The feature request is that coerce' should not be necessary

{-# LANGUAGE ScopedTypeVariables #-}
module FeatureRequest where

import Data.Coerce

data Iso a b = Iso (a -> b) (b -> a)

-- coerceIso :: Coercible a b => Iso a b -- desired
coerceIso :: (Coercible a b, Coercible b a) => Iso a b -- required
coerceIso = Iso coerce coerce

coerce' :: forall a b. Coercible a b => b -> a
coerce' = coerce (id :: a -> a)

coerceIso' :: Coercible a b => Iso a b -- work around
coerceIso' = Iso coerce coerce'

comment:5 Changed 3 years ago by goldfire

The following module compiles with 7.10 RC2 on my machine:

module T10156 where

import Data.Coerce

data Iso a b = Iso (a -> b) (b -> a)

coerceIso :: Coercible a b => Iso a b
coerceIso = Iso coerce coerce

This looks like what you want.

Is there something I'm missing here?

comment:6 Changed 3 years ago by ekmett

Resolution: invalid
Status: infoneededclosed
Version: 7.10.1-rc27.8.4

My mistake. It works in 7.10, but not 7.8. I was testing on the wrong box.

comment:7 Changed 3 years ago by Simon Peyton Jones <simonpj@…>

comment:8 Changed 3 years ago by simonpj

Test Case: typecheck/should_compile/T10156
Note: See TracTickets for help on using tickets.