gpt4 book ai didi

haskell - 如何在 IHP 脚本中重用 IHP 类?

转载 作者:行者123 更新时间:2023-12-02 16:25:59 25 4
gpt4 key购买 nike

我使用 IHP(haskell 网络框架)创建了一个网络应用程序。现在我想创建一个 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, 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"

最佳答案

FromNamedRecord 实例中,您缺少两个字段:idmetaid 字段是记录的第一个字段。 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

对于错误“Ambiguous occurrence ‘title’”,尝试使用 get 函数而不是使用普通的 haskell 访问函数:

putStrLn $ (get #title p) ++ ", " ++ show (get #price p) ++ " euro"

关于haskell - 如何在 IHP 脚本中重用 IHP 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64525488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com