2017-08-09 25 views
1

使用图案可变名称的整个情况下表达使其正确地编译和错误“无限类型推断为表达式”之间的差异。下面正确编译:无限型由于推断为图案可变

m = case Left "anything" of 
    [email protected](Left err) -> Left err 
    (Right f) -> case lookup "key" f of 
    Nothing -> Left "something else" 
    (Just x) -> Right x 

然而,如果我们使用图案变量e(为 “左ERR” 代即功能上等同),所述编译器标记的错误:

m = case Left "anything" of 
    [email protected](Left err) -> e 
    (Right f) -> case lookup "key" f of 
    Nothing -> Left "something else" 
    (Just x) -> Right x 

“无限类型被推断为表达式:StrMap t1,同时尝试将类型t1与类型StrMap t1匹配,同时检查表达式case((lookup“key”)f)...

我知道匹配StrMap t1和t1是有问题的。我不明白为什么会发生这种情况。另外,在我的ori中该消息没有涉及无限类型。下面是相关摘录:

retrieveDomeinResourceDefinition :: forall e. 
    ResourceId 
    -> Namespace 
    -> (AsyncDomeinFile e (Either String PropDefs)) 
retrieveDomeinResourceDefinition id ns = do 
    df <- retrieveDomeinFile (namespaceToDomeinFileName ns) 
    case df of 
    [email protected](Left err) -> pure $ e 
    (Right f) -> case lookup id f of 
     Nothing -> pure $ Left ("retrieveDomeinResourceDefinition: cannot find definition of " <> id <> " in DomeinFile for " <> ns) 
     (Just propDefs) -> pure (Right propDefs) 

retrieveDomeinFile :: forall e. Namespace -> AsyncDomeinFile e (Either String DomeinFile) 

newtype PropDefs = PropDefs (StrMap Json) 

现在,这里的编译器告诉我:“无法匹配类型:PropDefs型StrMap PropDefs ......”这看起来好像编译器不注意到查询表达式。事实上,当我取代“纯(右propDefs)”与“纯(右六)”,错误消失(和上线结合DF另一个出现,我的理解)。

现在我写这件事,我注意到“试图匹配类型StrMap T1型T1”和“不能匹配类型:PropDefs与StrMap PropDefs”之间的相似性。不过,我不明白为什么使用e引入了这个问题。

回答

2

使用模式匹配中的值可能在功能上等效,但类型不是 - 类型系统没有证据表明Right的类型变量可以被忽略。

在第二个例子中的类型 - 当你的模式匹配[email protected](Left err)e的类型将是Either String DomeinFile - 但你想要一个Either String PropDefs。模式匹配不“释放”就对了,这就是为什么你必须再次重建Left有错误的类型变量。

+0

我明白了。我错误地认为这些案件分裂为工会(每个案例都是工会的另一个成员),但是每个案例的类型都是整个工会。 –