是否可以使用类型类约束的类型同义词?
随意更改标题,我只是没有足够的经验知道真正发生了什么。
所以,我在这个基础上松散地编写了一个程序,并且写了这个程序(因为它是原始的)
type Row a    = [a]
type Matrix a = [Row a]
没有什么特别的。 但是,我发现自己用这样的一个类型编写了几个函数:
Eq a => Row a -> ...
所以我想,也许我可以将这个约束写入类型同义词定义中,因为在我看来,它不应该那么复杂,对吗? 如果编译器可以在函数中使用它,它应该作为一个类型的同义词工作。 这里没有部分应用程序或任何东西或某种欺骗(对我来说)。
所以我试过这个:
type Row a = Eq a => [a]
  这不起作用,编译器建议切换RankNTypes 。  该选项使它能够编译,但函数仍然要求我将Eq a =>留在它们的类型声明中。  顺便说一句,如果我尝试type Matrix a = [Row a]像以前一样type Matrix a = [Row a]的类型同义词,则会导致错误。 
所以我的问题是这样的:
在它的定义中是否有可能具有类型类型约束的类型同义词?
这个问题背后的目标是否可以通过其他方式实现?
类型变量上的约束不能成为任何Haskell类型签名的一部分。
  这似乎有点荒谬的说法:“什么是(==) :: Eq a => a -> a -> a然后?” 
  答案是a实际上并不存在,在几乎相同的方式没有真正的x定义中的fx = x * log x 。  你已经确定在定义该函数时使用了x符号,但实际上它只是在lambda抽象中使用的本地工具。  从外部访问这个符号绝对没有办法,事实上,编译器甚至不需要在机器代码中生成与x相对应的任何东西 - 它可能只是被优化掉了。 
事实上,任何多态签名基本上都可以读为接受类型变量的lambda表达式; 各种写作风格:
(==) :: forall a . Eq a => a -> a -> a
(==) :: ∀ a . Eq a => a -> a -> a
(==) :: Λa. {Eq a} -> a -> a -> a
这被称为系统F.
  请注意,是不是真的在此签名“约束”,而是一个额外的参数:该Eq -class字典。 
  通常你想避免在你的类型同义词中有约束,除非它真的有必要。  例如,从containers取得Data.Set API。 
  Data.Set许多操作要求该集合的元素是Ord实例,因为Set在内部实现为二叉树。  member或insert都需要Ord 
member :: Ord a => a -> Set a -> Bool
insert :: Ord a => a -> Set a -> Set a
  然而, Set的定义完全没有提及Ord 。 
  这是因为Set上的一些操作不需要Ord实例,如size或null 。 
size :: Set a -> Int
null :: Set a -> Bool
  如果类型约束是Set定义的一部分,这些函数将不得不包含约束,即使它不是必需的。 
  所以是的,可能在使用RankNTypes类型同义词中存在约束,但通常是不明智的。  最好为需要它们的函数编写约束。 
