问题描述
使用IHP(haskell Web框架),我创建了一个Web应用程序。现在,我想创建一个IHP脚本,以将一些外部数据加载到数据库中。但是我从Prelude中收到很多导入冲突,但不是我期望的类型。
#!/usr/bin/env run-script
module Application.Script.DataLoader where
import Application.Script.Prelude hiding (decode,pack,(.:))
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import Data.Text (pack)
import qualified Data.Vector as V
import Control.Monad (mzero)
instance FromNamedRecord Product where
parseNamedRecord r = Product def <$> r .: "title" <*> r .: "price" <*> r .: "category" <*> pure def
run :: Script
run = do
csvData <- BL.readFile "~/tender/data/Boiler-en-kookkraan_Boiler.csv"
case decodeByName csvData of
Left err -> putStrLn $ pack err
Right (_,v) -> V.forM_ v $ \ p ->
putStrLn $ (get #title p) ++ "," ++ show (get #price p) ++ " euro"
我的Product
模式如下:
CREATE TABLE products (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,title TEXT NOT NULL,price DOUBLE PRECISION NOT NULL,category TEXT NOT NULL
);
有没有一种方法可以将我创建为数据对象的类型用于例如读我的csv到?
[更新后的输出]
Application/Script/DataLoader.hs:12:26: error:
• Couldn't match type ‘MetaBag -> Product' a1’
with ‘Product' (QueryBuilder ProjectProduct)’
Expected type: Parser Product
Actual type: Parser (MetaBag -> Product' a1)
• In the expression:
Product def <$> r .: "title" <*> r .: "price" <*> r .: "category"
<*> pure def
In an equation for ‘parseNamedRecord’:
parseNamedRecord r
= Product def <$> r .: "title" <*> r .: "price" <*> r .: "category"
<*> pure def
In the instance declaration for ‘FromNamedRecord Product’
|
12 | parseNamedRecord r = Product def <$> r .: "title" <*> r .: "price" <*> r .: "category" <*> pure def
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[已解决,所有功劳都归于@mpscholten的帮助]
#!/usr/bin/env run-script
module Application.Script.DataLoader where
import Application.Script.Prelude hiding (decode,(.:))
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import Data.Text (pack)
import qualified Data.Vector as V
import Control.Monad (mzero)
parseProduct :: NamedRecord -> Parser Product
parseProduct r = do
title <- r .: "title"
price <- r .: "price"
category <- r .: "category"
newRecord @Product
|> set #title title
|> set #price price
|> set #category category
|> pure
run :: Script
run = do
csvData <- BL.readFile "data/Boiler-en-kookkraan_Boiler.csv"
case decodeByNameWithP parseProduct defaultDecodeOptions csvData of
Left err -> putStrLn $ pack err
Right (_," ++ show (get #price p) ++ " euro"
解决方法
您能否分享您确切遇到的错误?您所需的产品类型应位于Generated.Types
加载的实习生中的Application.Script.Prelude
中。
我认为您可能有两个都有字段标题的模型。在haskell字段中是函数,它们不能重复使用。
,在FromNamedRecord
实例中,您缺少两个字段:id
和meta
。 id
字段是记录的第一个字段。 meta
字段是IHP使用的隐藏字段,用于跟踪验证错误。它始终是记录的最后一个字段。
解决此问题的最简单方法是使用newRecord
并以更明确的方式写出代码:
instance FromNamedRecord Product where
parseNamedRecord r = do
title <- r .: "title"
price <- r .: "price"
category <- r .: "category"
newRecord @Product
|> set #title title
|> set #price price
|> set #category category
|> pure
对于错误“歧义出现”标题”,请尝试使用get
函数,而不要使用常规的haskell访问器函数:
putStrLn $ (get #title p) ++ "," ++ show (get #price p) ++ " euro"