Haskell中的应用程序是否保持类型相等?

Haskell中的应用程序是否保持类型相等?,haskell,types,Haskell,Types,在哈斯凯尔语中,skv~s1k1v1,其中s:*->*->*,是否意味着k~k1,v~v1,或s~s1?如果没有,为什么没有 我在编写一些实验代码时遇到了这种情况,其中一小部分是: newtype Article = Article String newtype ArticleId = ArticleId Int newtype Comment = Comment String newtype CommentId = CommentId Int data TableName k v where

在哈斯凯尔语中,
skv~s1k1v1
,其中
s:*->*->*
,是否意味着
k~k1
v~v1
,或
s~s1
?如果没有,为什么没有

我在编写一些实验代码时遇到了这种情况,其中一小部分是:

newtype Article = Article String
newtype ArticleId = ArticleId Int
newtype Comment = Comment String
newtype CommentId = CommentId Int

data TableName k v where
    Articles :: TableName ArticleId Article
    Comments :: TableName CommentId Comment    

data CRUD k v r where
    Create :: v -> CRUD k v k
    Read :: k -> CRUD k v (Maybe v)

data Operation t r where
    Operation :: s k v -> CRUD k v r -> Operation (s k v) r        

operatesOn :: (Eq (s k v)) => s k v -> Operation (s k v) r -> Bool
operatesOn tableName1 (Operation tableName2 _) = tableName1 == tableName2 
由于以下错误,无法编译:

Could not deduce (v1 ~ v)
from the context (Eq (s k v))
  bound by the type signature for
             operatesOn :: Eq (s k v) => s k v -> Operation (s k v) r -> Bool
or from (s k v ~ s1 k1 v1)
  bound by a pattern with constructor
             Operation :: forall r (s :: * -> * -> *) k v.
                          s k v -> CRUD k v r -> Operation (s k v) r,
           in an equation for `operatesOn'
  `v1' is a rigid type variable bound by
       a pattern with constructor
         Operation :: forall r (s :: * -> * -> *) k v.
                      s k v -> CRUD k v r -> Operation (s k v) r,
       in an equation for `operatesOn'
       at src\Example\Error.hs:44:24
  `v' is a rigid type variable bound by
      the type signature for
        operatesOn :: Eq (s k v) => s k v -> Operation (s k v) r -> Bool
      at src\Example\Error.hs:43:15
Expected type: s k v
  Actual type: s1 k1 v1
In the second argument of `(==)', namely `tableName2'
In the expression: tableName1 == tableName2
In an equation for `operatesOn':
    operatesOn tableName1 (Operation tableName2 _)
      = tableName1 == tableName2

如果我将操作的定义更改为

data Operation t r where
    Operation :: (t ~ s k v) => t -> CRUD k v r -> Operation t r
operatesOn函数将进行编译,类似于它在

(t~s k v)=>
约束(?)仍将拒绝不正确的程序,例如:


doesntCompile=Operation Article$Create$Comment“Yo”

还有另一个答案,它回答了我直接提出的问题,我讨论了
可能
数据类型会发生什么<代码>sameAsMaybe::(Eq(sk v))=>sk v->Maybe(sk v)->Bool定义为
sameAsMaybe a(Just b)=a==b
编译,这使我找到了这个解决方案。约束(?)-是的,它被称为整个示例完成了,它是为了回答这个问题:,但这不是问题。删除的答案包含了有用的见解。