Skip to content

Wingman won't apply return-type-polymorphic functions, even if they're the only things that would typecheck #1803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
isovector opened this issue May 6, 2021 · 0 comments
Labels
component: wingman type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..

Comments

@isovector
Copy link
Collaborator

isovector commented May 6, 2021

@masaeedu reports:

module Foo where

newtype Flip t a b = Flip { unFlip :: t b a }

newtype Co b f = Co { runCo :: forall r. b (Compose (Flip (->) r) f) -> r }

-- Records or products, pick one

data Something f = TheInt (f Int) | TheString (f String)

getTheInt :: Co Something f -> f Int
getTheInt (Co f) = f $ TheInt $ Compose $ Flip id

getTheString :: Co Something f -> f String
getTheString (Co f) = f $ TheString $ Compose $ Flip id

buildSomething :: (x -> f Int) -> (x -> f String) -> x -> Co Something f
buildSomething f g x = Co $ \case
  TheInt (Compose (Flip fi)) -> fi $ f x
  TheString (Compose (Flip fs)) -> fs $ g x

data SomethingElse f = SomethingElse { theInt :: f Int, theString :: f String }

buildAnInt :: f Int -> Co SomethingElse f
buildAnInt i = Co $ \SomethingElse { theInt = Compose (Flip x) } -> x i

buildAString :: f String -> Co SomethingElse f
buildAString s = Co $ \SomethingElse { theString = Compose (Flip x) } -> x s

matchSomethingElse :: (f Int -> r) -> (f String -> r) -> Co SomethingElse f -> r
matchSomethingElse f g (Co c) = c $ SomethingElse
  { theInt = Compose $ Flip f
  , theString = Compose $ Flip g
  }

fwd :: Co (Co Something) f -> Something f
fwd (Co c) = c $ Co $ \case
  TheInt (Compose (Flip fi)) -> fi $ Compose $ Flip TheInt
  TheString (Compose (Flip fs)) -> fs $ Compose $ Flip TheString

bwd :: Something f -> Co (Co Something) f
bwd = \case
  TheInt fi -> Co $ \(Co c) -> c $ TheInt $ Compose $ Flip $ \(Compose (Flip f)) -> f fi
  TheString fs -> Co $ \(Co c) -> c $ TheString $ Compose $ Flip $ \(Compose (Flip f)) -> f fs

Wingman should be able to produce fwd and bwd if given enough gas, but it doesn't! It gets stuck applying c, failing with a TooPolymorphic error. This appears to be caused by the call to requireConcreteHole in apply, which doesn't allow return-type-polymorphic calls. I've forgotten the original impetus for this, but it appears to be related to #534, and presumably to prevent Wingman from wasting its time solving holes via read and unsafeCoerce.

But there's another bug corresponding to requireConcreteHole:

-- TODO(sandy): This tactic doesn't fire for the @AutoThetaFix@ golden test,
-- presumably due to running afoul of 'requireConcreteHole'. Look into this!

which suggests we're barking up the entirely wrong tree with this check.

I think it's reasonable to requireConcreteHoles when applying non-local definitions, which would still rule out read and unsafeCoerce, but will allow recursion and application.

@isovector isovector added type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc.. component: wingman labels May 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: wingman type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..
Projects
None yet
Development

No branches or pull requests

2 participants