使用IHP ( haskell框架),我创建了一个web应用程序。现在,我想创建一个IHP脚本,将一些外部数据加载到我的数据库中。然而,我从前奏中得到了很多导入冲突,但不是我所期望的类型。
#!/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, 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)
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 (_, v) -> V.forM_ v $ \ p ->
putStrLn $ (get #title p) ++ ", " ++ show (get #price p) ++ " euro"发布于 2020-10-26 17:33:37
在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"发布于 2020-10-25 17:38:55
你能分享一下你所犯的错误吗?您想要的产品类型应该在Generated.Types中,实习生是由Application.Script.Prelude加载的。
我想你可能有两种型号都有现场标题。在haskell中,字段是函数,不能使用两次。
https://stackoverflow.com/questions/64525488
复制相似问题