如果没有匹配的封闭类型系列实例,是否有办法获得编译时错误?

Is there a way to get a compile-time error if there's no matching closed type family instance?

我有一个没有包罗万象的封闭型家庭:

{-# LANGUAGE TypeFamilies #-}

type family Foo a where
    Foo Bool = Int
    Foo Int = Bool

有没有办法强制类型检查器拒绝以下程序:

data T a = MkT deriving Show

x :: T (Foo String)
x = MkT

因为没有Foo String类型?

从 GHC 8.0.1 开始,可以这样写:

{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, UndecidableInstances #-}

import GHC.TypeLits

type family Foo a where
    Foo Bool = Int
    Foo Int  = Bool
    Foo a    = TypeError (Text "Invalid Foo " :<>: ShowType a)

data T a = MkT deriving Show

x :: T (Foo String)
x = MkT

模块可以加载,但是不能使用x:

*Main> :r
[1 of 1] Compiling Main             ( te.hs, interpreted )
Ok, modules loaded: Main.
*Main> x

<interactive>:18:1: error:
    • Invalid Foo [Char]
    • When checking the inferred type
        it :: T (TypeError ...)

如果你添加,没有类型签名

y = id x

GHC(i) 在类型检查期间抱怨:

te.hs:15:1: error:
    • Invalid Foo [Char]
    • When checking the inferred type
        y :: T (TypeError ...)

然而,如果您给 y 一个类型:y :: T (Foo String);那么 GHC 也会接受它。

我不确定这是错误还是功能。类型族,即使是封闭的,也不能任意减少,尤其是在 UndecidableInstances 存在的情况下,首先需要使用 TypeError。甚至像 whnf 这样的东西可能还不够,如果类型族会减少到 Maybe (TypeError ...).