Opened 2 years ago

Closed 2 years ago

Last modified 11 months ago

#13913 closed bug (duplicate)

Can't apply higher-ranked kind in type family

Reported by: RyanGlScott Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 8.0.1
Keywords: TypeFamilies, TypeInType Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: #11719 Differential Rev(s):
Wiki Page:

Description

This code doesn't typecheck due to F2:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
module Bug where

import Data.Kind

f :: (forall (a :: Type). a -> a) -> Bool
f g = g True

type F1 (g :: forall (a :: Type). a -> a) = g True

type family F2 (g :: forall (a :: Type). a -> a) :: Bool where
  F2 g = g True
$ /opt/ghc/8.2.1/bin/ghci Bug.hs
GHCi, version 8.2.0.20170623: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug              ( Bug.hs, interpreted )

Bug.hs:14:6: error:
    • Expected kind ‘forall a. a -> a’, but ‘g’ has kind ‘Bool -> Bool’
    • In the first argument of ‘F2’, namely ‘g’
      In the type family declaration for ‘F2’
   |
14 |   F2 g = g True
   |      ^

This is surprising to me, since F2 seems like the type family counterpart to f and F1, both of which typecheck.

Change History (4)

comment:1 Changed 2 years ago by goldfire

I believe this is a dup of #11719. My recent proposal around adding explicit foralls to type family equations will introduce a workaround. Perhaps a simple case like this, though, could be made to work.

comment:2 Changed 2 years ago by RyanGlScott

Resolution: duplicate
Status: newclosed

Oops, I didn't see that ticket! Thanks.

comment:3 Changed 11 months ago by RyanGlScott

I've found a workaround for this issue after much persistence. The trick is to associate F2 with a type class:

class C (g :: forall a. a -> a) where
  type F2 g :: Bool

Then, define a flexible instance like so, using an explicit forall to give g the appropriate higher-rank kind:

instance forall (g :: forall a. a -> a). C g where
  type F2 g = g True

That's it!

comment:4 Changed 11 months ago by simonpj

Keywords: TypeFamilies TypeInType added
Note: See TracTickets for help on using tickets.