简单的 liquidhaskell 示例未达到预期行为

Simple liquidhaskell example fails expected behavior

我最近开始玩液体 haskell,在我能找到的所有教程中,我找不到像下面这样的例子。

data MaybePerson = MaybePerson {                                                                        
  name' :: Maybe String,                                                                                
  age'  :: Maybe Int                                                                                    
}                                                                                                       

data Person = Person {                                                                                  
  name :: String,                                                                                       
  age  :: Int                                                                                           
}                                                                                                       

{-@ measure p :: MaybePerson -> Bool @-}                                                                
p (MaybePerson (Just _) (Just _)) = True                                                                
p _ = False                                                                                             

{-@ type JustPerson = {x:MaybePerson | p x} @-}                                                 

-- Attempts to instantiate a maybe person into a concrete Person                                    
{-@ getPerson :: JustPerson -> Person @-}                                               
getPerson (MaybePerson (Just name) (Just age)) = Person name age                             
getPerson _ = undefined 

如果我尝试以下操作,我的模块不会像预期的那样进行类型检查:

test = getPerson (MaybePerson Nothing Nothing) 

但是,由于某些原因,以下仍然没有类型检查:

test2 = getPerson (MaybePerson (Just "bob") (Just 25))

我得到了错误

Error: Liquid Type Mismatch

 36 | test2 = getPerson (MaybePerson (Just "bob") (Just 25))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   Inferred type
     VV : {v : MaybePerson | v == ?a}

   not a subtype of Required type
     VV : {VV : MaybePerson | Blank.p VV}

   In Context
     ?a : MaybePerson

此外,如果我省略 getPerson _ = undefined 行,我会得到

Your function is not total: not all patterns are defined.

尽管由于使用 liquidhaskell.

指定的前提条件,此功能显然是完整的

我在这里做错了什么?我基本上只是想能够用来自 Just 构造函数的 Maybe a 类型的子类型进行推理,但我找不到任何地方可以正确执行此操作的示例。

抱歉回复晚了!我应该找到一些方法来获得有关问题的通知。好的,有两件事正在发生,我们都应该解决!

首先,

出现了一些小故障
{-@ measure p :: MaybePerson -> Bool @-}                                                             

正确的语法只是

{-@ measure p @-}
p :: MaybePerson -> Bool

但是没有错误信息,所以你没有办法知道!

其次,当我更改上面的内容时,我仍然得到一些奇怪的错误 GHC.Maybe -- 我现在记不起确切的问题,会解决的 在我的笔记本电脑上,但为了便于说明,我将您的代码调整为:

{-@ LIQUID "--exact-data-cons" @-}

import Prelude hiding (Maybe (..))

data Maybe a = Just a | Nothing 

重新定义Maybe这应该不需要,我们会尽快找出解决方法

这样,您的代码就可以按原样工作,例如看这里

http://goto.ucsd.edu/liquid/index.html#?demo=permalink%2F1573693313_399.hs

所以你现在可以定义

{-@ getPerson :: JustPerson -> Person @-}                                               
getPerson (MaybePerson (Just name) (Just age)) = Person name age

并删除其他情况的等式。此外,

test1 = getPerson (MaybePerson Nothing Nothing)         -- error

产生类型错误,但下面是安全的

test2 = getPerson (MaybePerson (Just "bob") (Just 25))  -- ok

感谢您指出这一点,会解决的!