gpt4 book ai didi

haskell - 如何使用多片

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

我对 Yesod 完全陌生(并且在 haskell 方面不是很有经验),我正在尝试构建我的第一个处理程序。我使用默认参数来临时搭建我的应用程序(我使用 Yesod 0.9.4.1 版本并在临时搭建中选择 postgresql),现在我尝试使用 selectList 从表中检索一些数据。我在模型配置文件中定义了一个新表(我们称之为 Foo):

    Foo
xStart Int
yStart Int

并且想要传递 FooId 和其他一些 Foo 属性的列表,因此我定义了一条路由:

/foos/#Int/#Int/*FooId FoosReturnR GET

和一个处理程序:

    module Handler.FoosReturn where

import Import

selectWindowSize :: Int
selectWindowSize = 10000

getFoosReturnR :: Int -> Int -> [FooId] -> Handler RepPlain
getFoosReturnR x y withoutIds = do
foos <- runDB $ selectList [FooId /<-. withoutIds,
FooXStart <. x + selectWindowSize,
FooXStart >=. x - selectWindowSize,
FooYStart <. y + selectWindowSize,
FooYStart >=. y - selectWindowSize] []
return $ RepPlain $ toContent $ show foos

我在 Application.hs 中导入了处理程序并将其添加到 cabal 文件中,现在当我尝试运行它时,我收到一条错误,指出 FooId 不是 MultiPiece 的实例 - 但当我尝试将其设为实例时有错误指出 FooId 是类型同义词,不能是 MultiPiece 的实例 - 如何解决此问题?

<小时/>

编辑:Daniel:嗯,实际上我不知道 FooId 到底是什么 - 它是 Yesod 魔法的一部分,到目前为止我还没有完全理解 - 它是从表定义中自动生成的 - 但它是某种数字。

因为我不知道如何使用 MultiPiece,所以我切换到更简单的解决方案并进行了修改:

路线:/foos/#Int/#Int/#String FoosReturnR GET

处理程序:[还添加了一些日志记录]

    module Handler.FoosReturn where

import Import
import Data.List.Split
import qualified Data.Text.Lazy as TL

selectWindowSize :: Int
selectWindowSize = 10000

getFoosReturnR :: Int -> Int -> String -> Handler RepPlain
getFoosReturnR x y withoutIds = do
app <- getYesod
liftIO $ logLazyText (getLogger app) ("getFoosReturnR('" `TL.append` (TL.pack $ (show x) ++ "', '" ++ (show y) ++ "', '" ++ withoutIds ++ "') "))
foos <- runDB $ selectList [FooId /<-. (map (\a -> read a :: FooId) $ splitOn "," withoutIds),
FooXStart <. x + selectWindowSize,
FooXStart >=. x - selectWindowSize,
FooYStart <. y + selectWindowSize,
FooYStart >=. y - selectWindowSize] []
return $ RepPlain $ toContent $ show foos

现在它正在编译,但是当我浏览到:http://localhost:3000/sectors/1/1/1,2我得到的页面仅包含: 内部服务器错误 Prelude.read:无解析

好吧,我不完全理解这里的 FooId 是什么 - 如何从包含数字的字符串列表创建这样的 FooId 列表?

当然,最需要的是如何使 FooId 成为 MultiPiece 实例的解决方案。

<小时/>

编辑:

Daniel 和 svachalek,感谢您的帖子 - 我尝试了您(Daniel)的解决方案,但随后我收到错误,指出需要 [FooId](如处理程序函数声明中所示),但给出了 FooId 类型,这导致我解决方案如下:

    data FooIds = FooIds [FooId] deriving (Show, Read, Eq)

instance MultiPiece FooIds where
toMultiPiece (FooIds fooList) = map (Data.Text.pack . show) fooList
fromMultiPiece texts =
if length (filter isNothing listOfMaybeFooId) > 0
then Nothing
else Just $ FooIds $ map fromJust listOfMaybeFooId
where
listOfMaybeFooId = map constructMaybeFooId texts
constructMaybeFooId :: Text -> Maybe FooId
constructMaybeFooId x = case reads (Data.Text.unpack x) :: [(FooId,String)] of
[(foo,_)] -> Just foo
_ -> Nothing

当然,我将路线更改为:/foos/#Int/#Int/*FooIds FoosReturnR GET

和处理程序:

    getFoosReturnR :: Int -> Int -> FooIds -> Handler RepPlain
getFoosReturnR coordX coordY (FooIds withoutIds) = do

现在我在编译和运行时都没有收到任何错误,唯一不满意的是我总是收到 Not Found 结果,即使我提供了应该给我一些结果的参数 - 所以现在我有了弄清楚如何确定到底发送到数据库的 SQL 是什么

<小时/>

编辑:

现在我看到“未找到”与问题相关,并且上述编辑不是解决方案 - 当我浏览到 localhost:3000/foos/4930000/3360000 时,我得到结果(但随后 FooIds是空的) - 但是当我添加类似以下内容时: localhost:3000/sectors/4930000/3360000/1 然后我总是得到“未找到” - 所以它仍然无法正常工作..

最佳答案

希望我能帮忙,但据我所知,yesod 与 Web 应用程序有关,因此我从未真正研究过它。所以我可以尝试在空中刺一下,也许我击中了什么。

Hayoo 导致

class MultiPiece s where
fromMultiPiece :: [Text] -> Maybe s
toMultiPiece :: s -> [Text]

Yesod.Dispatch中。由于 FooId 似乎有一个 Read 实例,并且可能有一个 Show 实例,您可以尝试

{-# LANGUAGE TypeSynonymInstances #-}
-- maybe also FlexibleInstances

instance MultiPiece FooId where
toMultiPiece foo = [Text.pack $ show foo]
fromMultiPiece texts =
case reads (unpack $ Text.concat texts) :: [(FooId,String)] of
[(foo,_)] -> Just foo
_ -> Nothing

我不知道这是否接近正确的内容,我会把它作为评论发布,但它太长了,而且评论中没有太多格式。如果它没有帮助,我将删除它,以免给人留下你的问题已经有答案的印象,而实际上它还没有答案。

关于haskell - 如何使用多片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9113759/

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