2016-11-09 4 views
1

私はハスケルを完全に新しくしており、私はこの問題に対する答えを見つけることができません。多分私は間違ったことを探していたでしょう。ハスケルはIO UTCTimeを比較しています

私は2つのファイルパスと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 

:それはつまるところgetCurrentTimeはちょうどgetCurrentTimeのように、マニュアルに従ってIO UTCTime生成することになっている

Couldn't match expected type `UTCTime` 
with actual type `IO UTCTime` 
In the third argument of `doLoop`, namely `getCurrentTime` 

。私はここで何が欠けていますか?

+0

型署名を 'doLoop'に追加しようとすると、問題の内容がわかります。一方、 'doLoop'は3番目の引数が' UTCTime'であることを期待していますが、 'main'で呼び出すときに' IO UTCTime'を与えます。 mainを次のように変更してみてください: 'main = do {currTime < - getCurrentTime; doLoop "FilePath" "FilePath" currTime} '(または単に' main = doLoop "FilePath" "FilePath" = "currTime'をあなたが傾けている場合)。 – Alec

+0

チャームのように働いた。どうもありがとうございました!ハスケルがIO UTCTimeの代わりに非モナド的な引数を期待していた "do"コールがないためです。私が使用した関数はモナド結果しか生成できませんでした。 – Ozan

+0

@Ozanいいえ、 'IO'以外のものと一緒に'(/ =) 'に渡すので、非'IO'引数が必要です。 'do'構文を使うのか、最後に' IO'を作るのかは全く関係ありません。 –

答えて

3

IO UTCTimeは、タイムスタンプのタイプではありません。 のタイプで、タイムスタンプを与えることができるアクションです。これは大きな違いです。 doLoopはその最後の引数としてIO UTCTimeを受け入れるすることは、このように、あなたが欲しいのは、このようなタイプの署名を書き出すエラーが実際に起こっている場所を見つけるためにして文書化することはおそらく常に

doLoop :: FilePath -> FilePath -> UTCTime -> IO() 

である意味がありませんあなたの意図!

getCurrentTimeからアクションであるため、何その後、動作しませんが、doLoop "FilePath" "FilePath" getCurrentTimeではタイムスタンプではなく、実際のタイムスタンプを取得します。 (それだけで単一のタイムスタンプであれば、それはほとんど現在ことができなかった時はいつでもあなたは、それを、それを可能性が呼んで?)そこで

あなたはその後、doLoopに渡すことができ、実際のタイムスタンプを取得するために評価にこのアクションを必要とします。最も簡単な方法は、doブロックにあります。もっと簡潔

main = do 
    t <- getCurrentTime 
    doLoop "FilePath" "FilePath" t 

、あなたはまた、これらの2つのIOアクションKleisli-構成することができます。

main = doLoop "FilePath" "FilePath" =<< getCurrentTime 

...そのdo構文はにdesugars何実際には、とにかく

+0

を参照してください。私は、私がそのような関数を呼び出すと、現在のタイムスタンプを引数として挿入することを素朴に期待していました。私の間違いを指摘してくれてありがとう。 – Ozan

関連する問題