1

好的,我会更具体

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Database.Persist.TH
import Database.Persist.Sqlite
import Database.Esqueleto
import Control.Monad.IO.Class

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Topic
   title String
|]

main :: IO ()
main = do
  runSqlite "test.sqlite" $ do
       runMigration migrateAll
       [Value c1] <- select $
                     from $ \t ->
                     do
                           return countRows
       liftIO $ putStrLn $ show (c1 :: Int)

此代码导致错误

est2.hs:26:22: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘from’
  prevents the constraint ‘(From
                              SqlQuery SqlExpr SqlBackend a0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘a0’ should be.

那是因为编译器不知道它必须使用哪个表来计算行数。这件事可以通过类似的解决方法来完成

   [Value c1] <- select $
                 from $ \t ->
                     do
                       orderBy [asc (t ^. TopicTitle)]
                       return countRows
   liftIO $ putStrLn $ show (c1 :: Int)

然而,这是可怕的、乏味的和人为的。是否有另一种更简单的方法来修复此代码?

答案是:

我们应该说明表格,其中将计算行数。最简单的方法是使用 ScopedTypeVariables 语言扩展,并在本地描述参数的类型:

[Value c2] <- select $ from $ \(_ :: SqlExpr (Entity Topic)) -> do return countRows

4

0 回答 0