我试图了解使用forall
量化两个类型变量与使用forall
量化一个元组类型的单个变量之间的区别。
例如,给定以下类型族:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
type family Fst (p :: (a,b)) :: a where
Fst '(a,_) = a
type family Snd (p :: (a,b)) :: b where
Snd '(_,b) = b
type family Pair (p :: (Type,Type)) :: Type where
Pair '(a,b) = (a,b)
我可以使用两个类型变量在对上定义一个标识,并使其在GHC 8.0.1上编译:
ex0 :: forall (a :: Type) (b :: Type). Pair '(a,b) -> (Fst '(a,b), Snd '(a,b))
ex0 = id
但是,如果我使用元组类型的单个类型变量,则不会编译相同的定义:
ex1 :: forall (p :: (Type,Type)). Pair p -> (Fst p, Snd p)
ex1 = id
-- Ex.hs:20:7: error:
-- • Couldn't match type ‘Pair p’ with ‘(Fst p, Snd p)’
-- Expected type: Pair p -> (Fst p, Snd p)
-- Actual type: (Fst p, Snd p) -> (Fst p, Snd p)
-- • In the expression: id
-- In an equation for ‘ex1’: ex1 = id
-- • Relevant bindings include
-- ex1 :: Pair p -> (Fst p, Snd p) (bound at Ex.hs:20:1)
p
可能是⊥
的问题吗?
答案 0 :(得分:3)
原因仅仅是因为在类型级别上没有eta转换检查。首先,没有机制可以将data
定义与可能具有eta律的单构造记录/产品区分开。我认为p
可能是⊥
并不是这样做的正当理由。即使在部分惰性语言中,对的eta相等也成立(w.r.t.观察上的等效)。
答案 1 :(得分:3)
p
可能是⊥
的问题吗?
或多或少。不幸的是,空类型家庭居住着各种各样的东西。
type family Any :: k
哪个理论会让您尝试去做的事情感到沮丧。我认为确实需要修复;不过,我不确定是否有任何计划。