gpt4 book ai didi

haskell - 我能得到实现概念的帮助吗, "When a String changes, its type changes"

转载 作者:行者123 更新时间:2023-12-01 11:04:27 27 4
gpt4 key购买 nike

有一天在#haskell 上,有人提到了当字符串改变时字符串的类型应该如何改变的概念。这让我想起了我项目中的一些代码。它一直困扰着我,我说不清为什么。我现在推测,原因是我没有实现这个概念。这是下面的代码,然后是我如何开始改进它的一些想法。我想要的是对效果的一些输入,“你在正确的轨道上。”或者,“不,走远点。”,或者“这是你应该注意的另一件事。”。

> processHTML :: String -> [[String]]
> processHTML htmlFILE =
> let parsedHTML = parseTags htmlFILE
> allTagOpens = sections (~== TagOpen "a" [("href","")]) parsedHTML
> taggedTEXT = head $ map (filter isTagOpen) allTagOpens
> allHREFS = map (fromAttrib "href") taggedTEXT
> allPotentials = map (dropWhile (/= '?')) allHREFS
> removedNulls = filter (not . null) allPotentials
> removedQs = map (drop 1) removedNulls
> in map (splitOn "&") removedQs

这里的想法是我使用原始 HTML 并过滤掉所有我不想要的东西,直到我得到我想要的东西。每个 let 绑定(bind)代表过滤的一个阶段。这可能是数据结构的基础,如下所示:

> data Stage = Stage1 Foo
> | Stage2 Bar
> | Stage3 Baz

其中 Foo Bar 和 Baz 是合适的数据类型;例如,一个 String 或 TagOpen,具体取决于我在过滤过程中所处的阶段。当我添加错误处理代码时,我可以使用这种数据类型来获取准确的信息。此外,它还可以帮助我跟踪发生的事情。

感谢反馈。

最佳答案

你走在正确的轨道上。

首先,当您构建像这样的长管道时,您可能更愿意直接组合函数:

> processHTML :: String -> [[String]]
> processHTML =
> parseTags
> >>> sections (~== TagOpen "a" [("href","")])
> >>> head $ map (filter isTagOpen)
> >>> map (fromAttrib "href")
> >>> map (dropWhile (/= '?'))
> >>> filter (not . null)
> >>> map (drop 1)
> >>> map (splitOn "&")

这使用了 Control.Category.(>>>),这只是(至少在这种情况下)翻转函数组合。

现在对于您的实际问题,看起来您正在使用 tagsoup用于解析标签的包。这已经在整个管道中进行了一些类型更改:parseTags 生成一个 Tag,一些函数对其进行操作,然后 fromAttrib 返回到一个 String .

根据你要做的工作量,我可能会创建一个新类型:

newtype QueryElement = QE { unQE :: String } deriving (Eq, Show)

> processHTML :: String -> [[QueryElement]]
> processHTML =
> parseTags
> >>> sections (~== TagOpen "a" [("href","")])
> >>> head $ map (filter isTagOpen)
> >>> map (fromAttrib "href")
> >>> map (dropWhile (/= '?'))
> >>> filter (not . null)
> >>> map (drop 1)
> >>> map (splitOn "&" >>> map QE)

这里只有最后一行发生了变化,为每个元素添加了 QE newtype 标签。

根据您的用例,您可以采用不同的方法。例如,您可能希望向 URI 添加更多信息,而不是仅仅收集查询变量。或者您可能希望折叠查询项并直接生成 Map String String

最后,如果您试图获得类型安全,您通常不会创建像您的 Stage 这样的求和类型。这是因为每个构造函数都创建一个相同类型的值,所以编译器不能做任何额外的检查。相反,您将为每个阶段创建一个单独的类型:

data Stage1 = Stage1 Foo
data Stage2 = Stage2 Bar
data Stage3 = Stage3 Baz

doStage1 :: Stage1 -> Stage2

doStage2 :: Stage2 -> Stage3

创建非常细粒度的类和数据结构很容易,但在某些时候它们会失控。例如,在您的函数 allPotentialsremovedNullsremovedQs 中,您可能只想处理字符串。这些阶段的输出没有太多语义意义,尤其是当它们是稍大过程中的部分步骤时。

关于haskell - 我能得到实现概念的帮助吗, "When a String changes, its type changes",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7475716/

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