我正在使用 Liquid-haskell 做一些实验,看看我可以用它做什么样的整洁的事情,但我遇到了一些困难。基本思想是我有一些功能需要在经过一定时间后过期的访问令牌。我正在尝试了解如何使用liquid-haskell 来确保在将令牌传递给我的一个函数之前检查其有效性。我在下面创建了一个最小的工作版本来演示我的问题。当我在这个文件上运行液体时,我收到以下错误:
/tmp/liquidTest.hs:18:17-42: Error: Liquid Type Mismatch
18 | isExpired tok = currTime >= expiration tok
^^^^^^^^^^^^^^^^^^^^^^^^^^
Inferred type
VV : {VV : GHC.Types.Bool | Prop VV <=> Main.currTime >= ?a}
not a subtype of Required type
VV : {VV : GHC.Types.Bool | Prop VV <=> currTime >= expiration tok}
In Context
Main.currTime := Data.Time.Clock.UTC.UTCTime
tok := Main.Token
?a := {?a : Data.Time.Clock.UTC.UTCTime | ?a == expiration tok}
我似乎无法弄清楚为什么会出现这个错误并且我尝试过的一切都失败了。有人可以帮我吗?
另外,我想将时间包中的 currTime 函数替换为 getCurrentTime 函数。这样我就可以将令牌上的时间戳与当前时间进行比较。这意味着我的 isExpired 函数将是 Token -> IO Bool 类型。这甚至可以使用液体哈斯克尔吗?
import Data.Time
import Language.Haskell.Liquid.Prelude
{-@ data Token = Token
(expiration :: UTCTime)
@-}
data Token = Token
{ expiration :: UTCTime
} deriving Show
{-@ measure currTime :: UTCTime @-}
currTime :: UTCTime
currTime = UTCTime (ModifiedJulianDay 57614) 83924.978297
{-@ isExpired :: t:Token -> {v:Bool | ((Prop v) <=> (currTime >= expiration t))} @-}
isExpired :: Token -> Bool
isExpired tok = currTime >= expiration tok
{-@ type ValidToken = {t:Token | currTime < expiration t} @-}
{-@ showToken :: ValidToken -> String @-}
showToken :: Token -> String
showToken tok = show tok
main :: IO ()
main = do
ct <- getCurrentTime
let tok = Token ct
print currTime
case isExpired tok of
True -> putStrLn "The token has expired!"
False -> putStrLn $ showToken tok
谢谢!