我正在做一些使用液體哈斯克爾的實驗來看看我可以用它做什麼樣的整齊的事情,並且我碰到了一堵牆。基本思想是我有一些功能需要訪問令牌,在經過一段時間後過期。我試圖看看如何使用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}
我似乎無法找出爲什麼這個錯誤被顯示出來,一切我曾嘗試已經失敗。有人可以幫我嗎?
此外,我想用時間包中的getCurrentTime函數替換currTime函數。這樣我可以比較令牌上的時間戳和當前時間。這意味着我的isExpired函數的類型是Token - > IO Bool。這甚至可以使用液體haskell?
import Data.Time
import Language.Haskell.Liquid.Prelude
{[email protected] data Token = Token
(expiration :: UTCTime)
@-}
data Token = Token
{ expiration :: UTCTime
} deriving Show
{[email protected] measure currTime :: UTCTime @-}
currTime :: UTCTime
currTime = UTCTime (ModifiedJulianDay 57614) 83924.978297
{[email protected] isExpired :: t:Token -> {v:Bool | ((Prop v) <=> (currTime >= expiration t))} @-}
isExpired :: Token -> Bool
isExpired tok = currTime >= expiration tok
{[email protected] type ValidToken = {t:Token | currTime < expiration t} @-}
{[email protected] 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
謝謝!
感謝您的出色答案和工作演示的鏈接。這正是我需要的。 – ulbrec