我正在尝试在关于懒惰队列的 LiquidHaskell 案例研究中做第一个练习
module Main where
main :: IO ()
main = putStrLn "hello"
{-@ type Nat = {v:Int | 0 <= v} @-}
{-@ die :: {v:String | false} -> a @-}
die x = error x
{-@ measure realSize @-}
realSize :: [a] -> Int
realSize [] = 0
realSize (_:xs) = 1 + realSize xs
{-@ data SList a = SL {
size :: Nat
, elems :: {v:[a] | realSize v = size}
}
@-}
data SList a = SL { size :: Int, elems :: [a]}
{-@ type NEList a = {v:SList a | 0 < size v} @-}
{-@ hd :: NEList a -> a @-}
hd (SL _ (x:_)) = x
hd _ = die "empty SList"
okList = SL 1 ["cat"]
okHd = hd okList
okHd
失败:
app/Main.hs:30:13-18: Error: Liquid Type Mismatch
Inferred type
VV : {VV : (SList [Char]) | VV == Main.okList}
not a subtype of Required type
VV : {VV : (SList [Char]) | 0 < size VV}
In Context
VV : {VV : (SList [Char]) | VV == Main.okList}
Main.okList
: (SList [Char])
从错误消息中,我很确定我没有向 LH 提供足够的信息以使其“知道”okList
非空,但我不知道如何解决它。
我尝试用后置条件(?)明确地告诉它:
{-@ okList :: NEList a @-}
okList = SL 1 ["cat"]
但这不起作用:
app/Main.hs:29:5: Error: Specified Type Does Not Refine Haskell Type for Main.okList
Haskell: Main.SList [GHC.Types.Char]
Liquid : forall a. Main.SList a