2011-11-03 47 views
1

下面是代碼,我試着讓類型推理找出函數的類型。代碼編譯時,它在運行時失敗。有人可以向我解釋我應該如何解決這種類型的簽名?

Ambiguous type variables `b0', `m0' in the constraint: 
    (PersistBackend b0 m0) arising from a use of `isFree' 
Probable fix: add a type signature that fixes these type variable(s) 
In the expression: isFree testDay 
In an equation for `it': it = isFree testDay 

:t isFree

isFree :: PersistBackend b m => C.Day -> b m Bool

>isFree day = do 
    match <- selectList [TestStartDate ==. day, 
         TestStatus !=. Passed, 
         TestStatus !=. Failed] [] 
    if (L.null match) then (liftIO $ return True) else (liftIO $ return False) 

回答

1

這很尷尬。一方面,這個問題確實讓我深入到了Yesod monads的深處。另一方面,這個問題已經爲我解答。當你運行一個數據庫操作時,像這樣將結果傳遞給runDB。

>isFree day = do 
    match <- runDB $ selectList [TestStartDate ==. day, 
           TestStatus !=. Passed, 
           TestStatus !=. Failed] [] 
    if (L.null match) then (liftIO $ return True) else (liftIO $ return False) 
5

ghci的是告訴你,它不知道bm應選擇哪種類型的表達式。所有你需要做的就是告訴它,

isFree testDay :: Foo Bar Bool 

在實際的程序,這些類型變量在使用地點通常是確定的,所以你很少有在那裏指定表達式的類型。在ghci提示中,上下文丟失,所以你經常需要這樣做。

無關,isFree的最後一行將更好地爲return $ L.null match

+2

'liftIO(return x)'可能只是'return x'。不確定是否有任何「MonadIO」或「MonadTrans」實例的「法律」,但如果有,那肯定會是一個。 =) –

+0

不知道Foo和Bar需要什麼。 –

+0

D'oh。當然,謝謝。引用我最喜歡的簽名:「如果我沒有看到更進一步,那就是站在巨人的腳印下。」 –

1

「雖然代碼編譯,它無法在運行。」是不太可能在爲此功能提供類型時出錯。

「失敗」是什麼意思?

相關問題