我最近开始玩 Liquid 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 指定了先决条件。
我在这里做错了什么?我本质上只是希望能够对Maybe a
来自Just
构造函数的类型的子类型进行推理,但是我在任何地方都找不到任何可以正确执行此操作的示例。