Haskell Groundhog-Db 函数类型
Haskell Groundhog-Db function types
我是 haskell 的新手,我正在摆弄 postgreSQL 数据库上的 Groundhog-ORM 库。如果我将所有数据库内容放在一个函数中,一切都可以正常工作。但是,现在我想在不同的功能中分离不同的主题。
{-# LANGUAGE GADTs, TypeFamilies, TemplateHaskell, QuasiQuotes, FlexibleInstances, StandaloneDeriving #-}
module Main where
import System.IO
import Database.Groundhog.TH
import Database.Groundhog.Postgresql
import Data.DateTime
import Data.List.Split (splitOn)
import Control.Monad (mapM_, when, unless)
import Control.Monad.IO.Class (liftIO)
postgres_connection_string = "host=localhost port=5432 user=itsme password=unknown dbname=stocks"
data Symbol = Symbol {
name :: String
} deriving (Show, Eq)
mkPersist defaultCodegenConfig [groundhog|
definitions:
- entity: Symbol
dbName: symbols
schema: stocks
keys:
- name: unique_symbol
constructors:
- name: Symbol
uniques:
- name: unique_symbol
fields: [name]
|]
ensureSymbol :: (PersistBackend m) => String -> m (Symbol)
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
return (loadedSymbols !! 0)
main = do
contents <- readFile "src\inputTable.csv"
putStrLn ("Read " ++ show (length contents) ++ " Bytes input data.")
withPostgresqlConn postgres_connection_string . runDbConn $ do
liftIO $ putStrLn "About to ensure table structures."
runMigration $ do
migrate (undefined :: Symbol)
liftIO $ putStrLn "Checking for the symbol."
symbol <- ensureSymbol "EURUSD"
... [ Some more stuff ] ...
如您所见,我已经分离了一个从数据库中读取符号实体的小函数。这个例子编译正常。
但是,该函数被称为 ensureSymbol
而不是 readSymbol
,因此该函数应显示为
ensureSymbol :: (PersistBackend m) => String -> m (Symbol)
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
when (null loadedSymbols) (return (Symbol sym))
unless (null loadedSymbols) (return (loadedSymbols !! 0))
但现在我收到一堆错误消息,甚至在
行
loadedSymbols <- select (NameField ==. sym)
之前编译正确。我假设我需要一个额外的类型说明符来使 when
和 unless
对函数可见,但我不确定。
src\Main.hs:117:40:
Couldn't match type `Symbol' with `()'
In the first argument of `select', namely `(NameField ==. sym)'
In a stmt of a 'do' block:
loadedSymbols <- select (NameField ==. sym)
In the expression:
do { loadedSymbols <- select (NameField ==. sym);
when (null loadedSymbols) (return (Symbol sym));
unless (null loadedSymbols) (return (loadedSymbols !! 0)) }
src\Main.hs:118:40:
Couldn't match expected type `()' with actual type `Symbol'
In the first argument of `return', namely `(Symbol sym)'
In the second argument of `when', namely `(return (Symbol sym))'
src\Main.hs:119:5:
Couldn't match type `()' with `Symbol'
Expected type: m Symbol
Actual type: m ()
In a stmt of a 'do' block:
unless (null loadedSymbols) (return (loadedSymbols !! 0))
In the expression:
do { loadedSymbols <- select (NameField ==. sym);
when (null loadedSymbols) (return (Symbol sym));
unless (null loadedSymbols) (return (loadedSymbols !! 0)) }
也许有更优雅的方法来做到这一点?
when
和 unless
都具有相同的类型:
when, unless :: Monad m => Bool -> m () -> m ()
因此作为第二个参数传递的值必须具有类型 m ()
。在这两种情况下,您都通过了 m Symbol
。看起来你只想使用 if
:
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
if (null loadedSymbols) then (return (Symbol sym)) else (return (loadedSymbols !! 0))
或 case
:
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
case loadedSymbols of
[] -> return (Symbol sym)
s:ss -> return s
我是 haskell 的新手,我正在摆弄 postgreSQL 数据库上的 Groundhog-ORM 库。如果我将所有数据库内容放在一个函数中,一切都可以正常工作。但是,现在我想在不同的功能中分离不同的主题。
{-# LANGUAGE GADTs, TypeFamilies, TemplateHaskell, QuasiQuotes, FlexibleInstances, StandaloneDeriving #-}
module Main where
import System.IO
import Database.Groundhog.TH
import Database.Groundhog.Postgresql
import Data.DateTime
import Data.List.Split (splitOn)
import Control.Monad (mapM_, when, unless)
import Control.Monad.IO.Class (liftIO)
postgres_connection_string = "host=localhost port=5432 user=itsme password=unknown dbname=stocks"
data Symbol = Symbol {
name :: String
} deriving (Show, Eq)
mkPersist defaultCodegenConfig [groundhog|
definitions:
- entity: Symbol
dbName: symbols
schema: stocks
keys:
- name: unique_symbol
constructors:
- name: Symbol
uniques:
- name: unique_symbol
fields: [name]
|]
ensureSymbol :: (PersistBackend m) => String -> m (Symbol)
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
return (loadedSymbols !! 0)
main = do
contents <- readFile "src\inputTable.csv"
putStrLn ("Read " ++ show (length contents) ++ " Bytes input data.")
withPostgresqlConn postgres_connection_string . runDbConn $ do
liftIO $ putStrLn "About to ensure table structures."
runMigration $ do
migrate (undefined :: Symbol)
liftIO $ putStrLn "Checking for the symbol."
symbol <- ensureSymbol "EURUSD"
... [ Some more stuff ] ...
如您所见,我已经分离了一个从数据库中读取符号实体的小函数。这个例子编译正常。
但是,该函数被称为 ensureSymbol
而不是 readSymbol
,因此该函数应显示为
ensureSymbol :: (PersistBackend m) => String -> m (Symbol)
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
when (null loadedSymbols) (return (Symbol sym))
unless (null loadedSymbols) (return (loadedSymbols !! 0))
但现在我收到一堆错误消息,甚至在
行loadedSymbols <- select (NameField ==. sym)
之前编译正确。我假设我需要一个额外的类型说明符来使 when
和 unless
对函数可见,但我不确定。
src\Main.hs:117:40:
Couldn't match type `Symbol' with `()'
In the first argument of `select', namely `(NameField ==. sym)'
In a stmt of a 'do' block:
loadedSymbols <- select (NameField ==. sym)
In the expression:
do { loadedSymbols <- select (NameField ==. sym);
when (null loadedSymbols) (return (Symbol sym));
unless (null loadedSymbols) (return (loadedSymbols !! 0)) }
src\Main.hs:118:40:
Couldn't match expected type `()' with actual type `Symbol'
In the first argument of `return', namely `(Symbol sym)'
In the second argument of `when', namely `(return (Symbol sym))'
src\Main.hs:119:5:
Couldn't match type `()' with `Symbol'
Expected type: m Symbol
Actual type: m ()
In a stmt of a 'do' block:
unless (null loadedSymbols) (return (loadedSymbols !! 0))
In the expression:
do { loadedSymbols <- select (NameField ==. sym);
when (null loadedSymbols) (return (Symbol sym));
unless (null loadedSymbols) (return (loadedSymbols !! 0)) }
也许有更优雅的方法来做到这一点?
when
和 unless
都具有相同的类型:
when, unless :: Monad m => Bool -> m () -> m ()
因此作为第二个参数传递的值必须具有类型 m ()
。在这两种情况下,您都通过了 m Symbol
。看起来你只想使用 if
:
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
if (null loadedSymbols) then (return (Symbol sym)) else (return (loadedSymbols !! 0))
或 case
:
ensureSymbol sym = do
loadedSymbols <- select (NameField ==. sym)
case loadedSymbols of
[] -> return (Symbol sym)
s:ss -> return s