Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何从Haskell中的字符串列表中获取搜索匹配?_String_List_Haskell_Io - Fatal编程技术网

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

String 如何从Haskell中的字符串列表中获取搜索匹配?,string,list,haskell,io,String,List,Haskell,Io,如何从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 lis

如何从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 
主模块
哪里
导入列表
输入IO
导入单子
getLines=liftM行。读取文件
main=do
putStrLn“请输入您的姓名:”

name如果您不想在list.txt中列出包含该名称的所有行, 你可以简单地使用

filter (isInfixOf name) list

但是我不确定我是否理解了你的问题。

首先要做的事情,最重要的第一原则,是尽可能多地从
main
IO
中思考
main
应尽可能包含所有
IO
,可能只包含
IO
,并用模块中其他地方定义的纯术语修饰。您的
getLines
不必要地混合了它们

所以,为了解决这个问题,我们应该有一个
main
,它类似于

main = 
   do putStrLn "What is your name?"
      name <- getContents
      names <- readFile "names.txt"
      putStrLn (frankJ name names)
连同“纯”术语:

greeting, nameFile :: String
greeting = "What is your name?"
nameFile = "names.txt"
不管怎样,我们现在真的在Haskell土地上:现在的问题是找出什么是纯函数:

应该是

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

 match :: String -> [String] -> Bool
 match name namelist = name `elem` namelist  
 -- pretty clever, that!
或者,我们可能希望规范化一点,以便在给定名称的开头和结尾使用空格,并且列表中的名称不会影响匹配。这里有一个相当简陋的方法:

 clean :: String -> String
 clean =  reverse . omitSpaces . reverse . omitSpaces
   where omitSpaces = dropWhile (== ' ')
然后我们可以改进旧的
匹配
,即
元素

 matchClean :: String -> [String] -> Bool
 matchClean name namelist = match (clean name) (map clean namelist)
现在我们需要遵循这些类型,找出如何将
matchClean::String->[String]->Bool
的类型与
frankJ::String->String->String
的类型相匹配。我们想把它放在
frankJ
的定义中

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

但我们还需要决定如何处理
Bool
,该
matchClean
产生的值
frankJ
,正如我们所看到的,返回一个
字符串。让我们继续简单地分解问题:

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!"
现在我们有了材料,我们可以为函数
frankJ::String->String->String->String
组合成一个合理的候选者,我们将该函数输入到
IO
机器中,该机器在
main
中定义:

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
所以在这里,几乎所有的事情都是纯函数的问题,很容易看到如何对它们进行修正以进一步细化。例如,可能输入的名称和文本文件的行应该进一步规范化。在比较之前,内部空间应限制为一个空间。或者列表中的行中可能有逗号,因为人们被列为“lastname,firstname”,等等。或者我们希望响应函数使用这个人的名字:

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是否可以使用它


我注意到您对导入的模块使用的是老式名称。我所写的只是前奏曲,因此导入是不必要的,但根据层次命名系统,其他模块现在被称为“System.IO”、“Data.List”和“Control.Monad”。我想知道你是否在使用旧的教程或手册。也许愉快的“向你学习Haskell”网站会更好?他肯定自己正在使用ghc,但我认为这不会有多大影响

list.txt的内容是如何格式化的?我猜您想筛选包含单词名称的行?
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