gpt4 book ai didi

string - 如何从 Haskell 中的字符串列表中获取搜索匹配项?

转载 作者:行者123 更新时间:2023-12-02 11:38:31 26 4
gpt4 key购买 nike

如何从 Haskell 中的字符串列表中获取搜索匹配项?

module Main
where
import List
import IO
import Monad

getLines = liftM lines . readFile

main = do
putStrLn "Please enter your name: "
name <- getLine
list <- getLines "list.txt"
-- mapM_ putStrLn list -- this part is to list out the input of lists

最佳答案

要做的第一件事,也是最重要的首要原则,是尽可能多地从 mainIO 中获取思考。 main 应尽可能包含所有 IO,也许除了用您在模块中其他地方定义的纯术语装饰的 IO 之外什么也不包含。您的 getLines 不必要地混合了它们。

因此,为了解决这个问题,我们应该有一个类似的 main

main = 
do putStrLn "What is your name?"
name <- getContents
names <- readFile "names.txt"
putStrLn (frankJ name names)

--或者可能是 IO 与我们获得的其他所有内容的更严格的隔离:

main = 
do putStrLn greeting
name <- getContents
names <- readFile nameFile
putStrLn (frankJ name names)

与“纯粹”术语一起:

greeting, nameFile :: String
greeting = "What is your name?"
nameFile = "names.txt"

无论哪种方式,我们现在都真正进入了 Haskell 世界:现在的问题是弄清楚纯函数:

 frankJ :: String -> String -> String

应该是。

我们可以从一个简单的匹配函数开始:当第一个字符串出现在字符串列表中时,我们得到一个匹配:

 match :: String -> [String] -> Bool
match name namelist = name `elem` namelist
-- pretty clever, that!

或者我们可能想要标准化一点,以便我们给出的名称的开头和结尾处的空格以及列表中的名称不会影响匹配。这是一个相当糟糕的方法:

 clean :: String -> String
clean = reverse . omitSpaces . reverse . omitSpaces
where omitSpaces = dropWhile (== ' ')

然后我们可以改进旧的匹配,即elem:

 matchClean :: String -> [String] -> Bool
matchClean name namelist = match (clean name) (map clean namelist)

现在我们需要遵循类型,弄清楚如何将 matchClean::String -> [String] -> Bool 的类型与 frankJ::的类型相匹配字符串 -> 字符串 -> 字符串。我们希望将其放入 frankJ 的定义中。

因此,为了为 matchClean '提供输入',我们需要一个函数来将我们从带有换行符的长字符串带到 matchClean 的字符串(名称)列表> 需求:这就是 Prelude 函数 lines

但是我们还需要决定如何处理 matchClean 生成的 Bool 作为值;正如我们所知,frankJ 返回一个String。让我们继续简单地分解问题:

response :: Bool -> String
response False = "We're sorry, your name does not appear on the list, please leave."
response True = "Hey, you're on the A-list, welcome!"

现在我们有了 Material ,可以将其组合成函数 frankJ::String -> String -> String 的合理候选者,我们将其输入到我们定义的 IO 机器中在中:

frankJ name nametext = response (matchClean name (lines nametext))

-- or maybe the fancier:
-- frankJ name = response . matchClean name . lines
-- given a name, this
-- - pipes the nametext through the lines function, splitting it,
-- - decides whether the given name matches, and then
-- - calculates the 'response' string

所以在这里,几乎一切都是纯函数的问题,并且很容易看出如何修改事物以进一步细化。例如,也许输入的名称和文本文件的行应该进一步规范化。在比较之前,内部空间应限制为一个空间。或者列表中的行中可能有一个逗号,因为人们被列为“姓氏、名字”等。或者也许我们希望响应函数使用该人的姓名:

personalResponse :: String -> Bool -> String
personalResponse name False = name ++ " is a loser, as far as I can tell, get out!"
personalResponse name True = "Ah, our old friend " ++ name ++ "! Welcome!"

一起
frankJpersonal name = personalResponse name . matchClean name . lines

当然有一百万种方法可以解决这个问题。例如,有regex库。 Hackage 中优秀且简单的 Data.List.Split 也可能有用,但我不确定它是否可以被 Hugs 使用,您可能正在使用 Hugs。

我注意到您对导入的模块使用旧式名称。我编写的内容仅使用 Prelude,因此不需要导入,但其他模块现在根据分层命名系统称为“System.IO”、“Data.List”和“Control.Monad”。我想知道您是否使用旧的教程或手册。也许令人愉快的“Learn You a Haskell”网站会更好?他确认他正在使用 ghc,但我认为这不会产生太大影响。

关于string - 如何从 Haskell 中的字符串列表中获取搜索匹配项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5848715/

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