Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,844
    • Issues 4,844
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 453
    • Merge requests 453
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #12176

Closed
Open
Created Jun 10, 2016 by Richard Eisenberg@raeDeveloper

Failure of bidirectional type inference at the kind level

I'm feeling particularly sadistic towards GHC at the moment, and so I fed it this:

import Data.Kind

data Proxy :: forall k. k -> Type where
  MkProxy :: forall k (a :: k). Proxy a

data X where
  MkX :: forall (k :: Type) (a :: k). Proxy a -> X

type Expr = (MkX :: forall (a :: Bool). Proxy a -> X)

type family Foo (x :: forall (a :: k). Proxy a -> X) where
  Foo (MkX :: forall (a :: k). Proxy a -> X) = (MkProxy :: Proxy k)

Incredibly, GHC accepts it! And it even means what I wish it to, with GHCi telling me the following (with -fprint-explicit-kinds):

λ> :i Foo
type family Foo k (x :: forall (a :: k). Proxy k a -> X)
            :: Proxy * k
  where [k] Foo k ('MkX k) = 'MkProxy * k

That is, I wished to extract the kind parameter to MkK, matching against a partially-applied MkX, and GHC understood that intention.

However, sadly, writing Foo Expr produces

    • Expected kind ‘forall (a :: k0). Proxy k0 a -> X’,
        but ‘Expr a0’ has kind ‘Proxy Bool a0 -> X’
    • In the first argument of ‘Foo’, namely ‘Expr’
      In the type ‘Foo Expr’
      In the type family declaration for ‘XXX’

For some reason, Expr is getting instantiated when it shouldn't be.

Perhaps there's a simpler test case demonstrating the bug, but I feel so gleeful that this chicanery is accepted at all that I wanted to post.

Edited Mar 10, 2019 by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking