我是Haskell的新手,我找不到这个问题的答案。也许我在寻找错误的东西。
我遇到了一个小脚本问题,该脚本应该采用两个文件路径和一个IO UTCTime
时间戳。我们的想法是每5秒检查一次目录是否被修改。为简单起见,我省略了脚本的细节。归结为:
import Data.List
import Control.Monad
import Control.Concurrent
import System.Directory
import Data.Time.Clock
main = doLoop "FilePath" "FilePath" getCurrentTime
doLoop lastPath currentPath lastModified = do
modified <- getModificationTime currentPath
if (lastModified /= modified)
then print "Success"
else do threadDelay 5000000
doLoop "FilePath" "FilePath" lastModified
我收到了编译错误:
Couldn't match expected type `UTCTime`
with actual type `IO UTCTime`
In the third argument of `doLoop`, namely `getCurrentTime`
根据文档, getCurrentTime应该生成IO UTCTime
,就像getCurrentTime
一样。我在这里缺少什么?
答案 0 :(得分:3)
IO UTCTime
不是时间戳的类型。这是一种可以为您提供时间戳的动作类型。这是一个巨大的差异。因此,doLoop
接受IO UTCTime
作为其最后一个参数是没有意义的,你想要的可能是
doLoop :: FilePath -> FilePath -> UTCTime -> IO ()
总是写出这样的类型签名,找出错误发生的位置并记录你的意图!
不起作用的是doLoop "FilePath" "FilePath" getCurrentTime
,因为getCurrentTime
是获取时间戳而不是实际时间戳的操作。 (如果它只是一个时间戳,那么只要你打电话就很难当前,是吗?)
因此,您需要评估此操作以获取实际时间戳,然后您可以将其传递给doLoop
。最简单的方法是do
块:
main = do
t <- getCurrentTime
doLoop "FilePath" "FilePath" t
更简洁地说,您也可以Kleisli撰写这两个IO
行动:
main = doLoop "FilePath" "FilePath" =<< getCurrentTime
......无论如何,这实际上是do
语法所贬低的。