为什么 TypeApplications 不允许使用部分应用的类型同义词

Why doesn't TypeApplications allow partially applied type synonyms to be used

我做了一些搜索并认为 LiberalTypeSynonyms 会允许它。在某些情况下,它允许使用 partially applied type synonyms 作为 Type 的参数。

{-# LANGUAGE LiberalTypeSynonyms #-}

type Value a = ExceptT [a] Identity a
type Apply m a = m a
run1 :: Apply Value a -> IO ()
run1 e = undefined 

但以下在 TypeApplications 中不起作用,为什么并且可以编译它?

{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE TypeApplications #-}

type Value a = ExceptT [a] Identity a

run :: m Int -> IO ()
run e = undefined 

main :: IO ()
main = do
    print "begin"
    let a = run @Value 
    print "end"

以上代码因错误无法编译

    • The type synonym ‘Value’ should have 1 argument, but has been given none
    • In the expression: run @Value
      In an equation for ‘a’: a = run @Value
      In the expression:
        do print "begin"
           let a = run @Value
           print "end"
   |
30 |     let a = run @Value 

这与-XTypeApplications没有太大关系。 Haskell 通常 不允许在没有完全应用参数的情况下使用类型同义词。 -XLiberalTypeSynonyms 所做的只是规避这一点,以防可以内联整个表达式——例如如果你有

{-# LANGUAGE LiberalTypeSynonyms #-}

type IntApplied f = f Int
type List a = [a]

foo :: IntApplied List
foo = [1,2,3]

在这种情况下,在进行任何类型检查或实例解析之前,可以直接将类型同义词替换为 foo :: [Int]。这就像一个简单的宏处理器可以做的事情。

但在您的情况下,您正试图将不完整的类型同义词传递给其他东西 as-is。 run 不知道它接收的类型变量是否可以通过这种方式“内联”,但通常需要能够 匹配 这个变量,这在一般的 type-level 函数上是不可能的(因为你可以用类型 synonyms/families 定义),它只在 类型的构造函数 .

上才有可能

请参阅 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0242-unsaturated-type-families.rst 以了解 Haskell 如何在此主题上取得进展。