Haskell 为什么可以';t type Id a=a是否部分应用于数据df=D(f())?

Haskell 为什么可以';t type Id a=a是否部分应用于数据df=D(f())?,haskell,ghc,Haskell,Ghc,我还尝试了中建议的LiberalTypeSynonyms扩展,并在Id的定义中为f添加了明确的种类符号。我还是犯了同样的错误。我不知道是否有其他的扩展可能会有所帮助 ghci> type Id a = a ghci> type Const a b = a ghci> data D f = D (f ()) ghci> (((() :: Id ()) :: ()) :: Const () a) () ghci> D () :: D Id <interactiv

我还尝试了中建议的LiberalTypeSynonyms扩展,并在
Id
的定义中为
f
添加了明确的种类符号。我还是犯了同样的错误。我不知道是否有其他的扩展可能会有所帮助

ghci> type Id a = a
ghci> type Const a b = a
ghci> data D f = D (f ())
ghci> (((() :: Id ()) :: ()) :: Const () a)
()
ghci> D () :: D Id

<interactive>:10:9:
    Type synonym ‘Id’ should have 1 argument, but has been given none
    In an expression type signature: D Id
    In the expression: D () :: D Id
    In an equation for ‘it’: it = D () :: D Id
ghci>类型Id a=a
ghci>类型常数a b=a
ghci>数据D f=D(f())
ghci>((()::Id())::())::常量()a)
()
ghci>D()::D Id
:10:9:
类型同义词“Id”应具有1个参数,但未提供任何参数
在表达式类型签名中:D Id
在表达式中:D()::D Id
在“it”的等式中:it=D()::D Id

这真让我困惑<
D
中的code>f是
*->*
Id
*->*
。还有什么呢?

Haskell的类型系统不支持部分应用(也称为不饱和)类型同义词或族<代码>数据类型和
新类型
确实支持部分应用程序

newtype D f = D (f ())
newtype Id a = Id a

d :: D Id
d = D (Id ())

newtype
s在编译过程中会被删除,因此您要支付的唯一成本是语法成本。

部分应用的类型同义词本质上等同于类型级别的lambda,这使得类型检查算法更加复杂。GHC不允许这样做。改为使用
newtype
s或
data
s包装器,并根据需要使用构造函数包装/展开值。否则,换成Agda或Coq:-PBy顺便说一句,自由类型同义词规则并没有给你更多的灵活性,只是一点点。如果在扩展了所有类型同义词之后,仍有部分应用的同义词,则会触发类型错误。如果您使用
类型df=f()
,则扩展将允许您的代码。但是
df
f()
@chi的类型相同,后者为我澄清了扩展。不幸的是,在我的特殊问题中,我不能将D作为类型同义词,但我可能会将Id和Const作为新类型。你的“这对GHC来说太复杂了”评论可以作为一个答案。如果你这样发布,我可能会接受,但也许我应该再等一点,以防其他人也想发布。@Bakuriu你问题中的两个例子都使用
LiberalTypeSynonyms
编译;然而,即使使用
liberaltype同义词
,这个问题中的示例也无法编译。所以我同意你的观点,它是相关的,但与jlmg无关,它是重复的。除非它不是:(.Ed Kmett想添加
liftCercion::Maybe(强制a b->强制(f a)(f b))
Functor
类,以及类似于
逆变
双Functor
Profunctor
的方法,以使强制更普遍适用,从而使新类型更自由。