goldfirere / ghc

Mirror of ghc repository. DO NOT SUBMIT PULL REQUESTS HERE
http://www.haskell.org/ghc/
Other
25 stars 1 forks source link

assertion failure (in incorrect code) #25

Open sweirich opened 9 years ago

sweirich commented 9 years ago

Prelude> :r [1 of 1] Compiling Singletons ( singletons.hs, interpreted ) *\ Exception: ASSERT failed! file compiler/typecheck/TcCanonical.hs, line 1093

{-# LANGUAGE GADTs, PolyKinds, TypeOperators, TemplateHaskell,
             DataKinds, TypeFamilies, UndecidableInstances,
             FlexibleContexts, RankNTypes, ScopedTypeVariables,
             FlexibleInstances #-}
{-# OPTIONS_GHC -fwarn-unticked-promoted-constructors #-}

module Singletons where

-- A version of singletons designed to work with kind equalities
-- and with typelits

import Data.Type.Equality
import GHC.Exts
import Data.Type.Bool
import Data.Proxy

import GHC.TypeLits
import Unsafe.Coerce

-- basic singletons stuff

data family Sing (a :: k)

class SingI (a :: k) where sing :: Sing a

class SingKind k where
  type DemoteRep k :: *
  fromSing :: Sing (x :: k) -> DemoteRep k

----------------------------------------------------------------------
---- SingInstance ----------------------------------------------------
----------------------------------------------------------------------

-- | A 'SingInstance' wraps up a 'SingI' instance for explicit handling.
data SingInstance (a :: k) where
  SingInstance :: SingI a => SingInstance a

-- dirty implementation of explicit-to-implicit conversion
newtype DI a = Don'tInstantiate (SingI a => SingInstance a)

-- | Get an implicit singleton (a 'SingI' instance) from an explicit one.
singInstance :: forall (a :: k). Sing a -> SingInstance a
singInstance s = with_sing_i SingInstance
  where
    with_sing_i :: (SingI a => SingInstance a) -> SingInstance a
    with_sing_i si = unsafeCoerce (Don'tInstantiate si) s

withSingI :: Sing n -> (SingI n => r) -> r
withSingI sn r =
  case singInstance sn of
    SingInstance -> r

----------------------------------------------------------------------
-- singletons and type-lit natural numbers 
----------------------------------------------------------------------

data instance Sing (n :: Nat) = KnownNat n => SNat

instance KnownNat n => SingI n where sing = SNat

instance SingKind Nat where
  type DemoteRep Nat = Integer
  fromSing (SNat :: Sing n) = natVal (Proxy :: Proxy n)

sEqNat :: forall a b. Sing a -> Sing b -> Maybe (a :~: b)
sEqNat s1 s2 = 
  withSingI s1 $ withSingI s2 $ sameNat (Proxy :: Proxy a) (Proxy :: Proxy b)
sweirich commented 9 years ago

The code is not type correct because I was confusing KnownNat and SingI constraints.