考虑以下代码
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
module Test () where
import Data.Proxy
import Data.Void
import GHC.TypeLits
data N = S N | Z
type family Index e l where
Index e (Either e x) = 'Z
Index e (Either e' y) = S (Index e y)
Index e Void = TypeError ('Text " not found")
在GHCi上加载这个我运行跟随
λ> :set -XRankNTypes
λ> :kind! forall a . Index a (Either a Void)
forall a . Index a (Either a Void) :: N
= 'Z
λ> :kind! forall a . Index a (Either a (Either Int Void))
forall a . Index a (Either a (Either Int Void)) :: N
= 'Z
λ> :kind! forall a . Index a (Either Int (Either a Void))
forall a . Index a (Either Int (Either a Void)) :: N
= Index a (Either Int (Either a Void))
λ> :kind! Index Char (Either Int (Either Char Void))
Index Char (Either Int (Either Char Void)) :: N
= 'S 'Z
现在很明显GHC没有评估Index e (Either Int y) =
S (Index e y)
,因为e
可能是Int
所以它就会停止。有没有
普遍量化e
的方法,以便e ~ Int
不起作用
forall e
,然后继续?理想情况下,我想得到:
λ> :kind! forall a . Index a (Either Int (Either Char Void))
forall a . Index a (Either Int (Either Char Void)) :: N
= 'S ('S (TypeError ...))