haskell单词搜索程序开发

发布于 2024-11-10 16:01:05 字数 1644 浏览 4 评论 0原文

你好,我正在制作一些单词搜索程序,

例如

,当“text.txt”文件包含“foo foos foor fo.. foo folool”

并搜索“foo”,

然后只打印数字2

并一次又一次搜索,

但我是haskell初学者

我的代码在这里

:module +Text.Regex.Posix
putStrLn "type text file"
filepath <- getLine
data <- readFile filepath

--1. this makes <interactive>:1:1: parse error on input `data' how to fix it?

parsedData =~ "[^- \".,\n]+" :: [[String]]

--2. I want to make function and call it again and again
searchingFunc = do putStrLn "search for ..."
        search <- getLine
        result <- map (\each -> if each == search then count = count + 1) data
        putStrLn result
        searchingFunc
}

抱歉非常非常糟糕的代码

我的开发环境是 Windows XP SP3 WinGhci 1.0.2

我几个小时前启动了 haskell 抱歉

非常感谢您的阅读!

编辑:这是原始方案代码

谢谢!

#lang scheme/gui
(define count 0)
(define (search str)
  (set! count 0)
  (map (λ (each) (when (equal? str each) (set! count (+ count 1)))) data)
  (send msg set-label (format "~a Found" count)))   

(define path (get-file))
(define port (open-input-file path))
(define data '())
(define (loop [line (read-line port)]) 
  (when (not (eof-object? line))
    (set! data (append data 
                       (regexp-match* #rx"[^- \".,\n]+" line)))
    (loop)))
(loop)
(define (cb-txt t e) (search (send t get-value)))
(define f (new frame% (label "text search") (min-width 300)))
(define txt (new text-field% (label "type here to search") (parent f) (callback (λ (t e) (cb-txt t e)))))
(define msg (new message% (label "0Found           ") (parent f)))
(send f show #t)

hello I am making some word searching program

for example

when "text.txt" file contains "foo foos foor fo.. foo fool"

and search "foo"

then only number 2 printed

and search again and again

but I am haskell beginner

my code is here

:module +Text.Regex.Posix
putStrLn "type text file"
filepath <- getLine
data <- readFile filepath

--1. this makes <interactive>:1:1: parse error on input `data' how to fix it?

parsedData =~ "[^- \".,\n]+" :: [[String]]

--2. I want to make function and call it again and again
searchingFunc = do putStrLn "search for ..."
        search <- getLine
        result <- map (\each -> if each == search then count = count + 1) data
        putStrLn result
        searchingFunc
}

sorry for very very poor code

my development environment is Windows XP SP3 WinGhci 1.0.2

I started the haskell several hours ago sorry

thank you very much for reading!

edit: here's original scheme code

thanks!

#lang scheme/gui
(define count 0)
(define (search str)
  (set! count 0)
  (map (λ (each) (when (equal? str each) (set! count (+ count 1)))) data)
  (send msg set-label (format "~a Found" count)))   

(define path (get-file))
(define port (open-input-file path))
(define data '())
(define (loop [line (read-line port)]) 
  (when (not (eof-object? line))
    (set! data (append data 
                       (regexp-match* #rx"[^- \".,\n]+" line)))
    (loop)))
(loop)
(define (cb-txt t e) (search (send t get-value)))
(define f (new frame% (label "text search") (min-width 300)))
(define txt (new text-field% (label "type here to search") (parent f) (callback (λ (t e) (cb-txt t e)))))
(define msg (new message% (label "0Found           ") (parent f)))
(send f show #t)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

遥远的绿洲 2024-11-17 16:01:05

我应该首先重申每个人都会(并且应该)说的话:从一本像 Real World Haskell 这样的书开始!也就是说,我将发布一个可编译的代码的快速演练,并希望能完成一些接近您最初意图的事情。评论是内联的,希望能够说明您的方法的一些缺点。

import Text.Regex.Posix                                                               

-- Let's start by wrapping your first attempt into a 'Monadic Action'
-- IO is a monad, and hence we can sequence 'actions' (read as: functions)
-- together using do-notation.                                                                 
attemptOne :: IO [[String]]
-- ^ type declaration of the function 'attemptOne'
-- read as: function returning value having type 'IO [[String]]'                                                            
attemptOne = do                                                                        
  putStrLn "type text file"                                                            
  filePath <- getLine                                                                  
  fileData <- readFile filePath                                                        
  putStrLn fileData                                                                    

  let parsed = fileData =~ "[^- \".,\n]+" :: [[String]]
  -- ^ this form of let syntax allows us to declare that
  -- 'wherever there is a use of the left-hand-side, we can
  -- substitute it for the right-hand-side and get equivalent
  -- results.                            
  putStrLn ("The data after running the regex: " ++ concatMap concat parsed)           

  return parsed                                      
  -- ^ return is a monadic action that 'lifts' a value
  -- into the encapsulating monad (in this case, the 'IO' Monad).                                  

-- Here we show that given a search term (a String), and a body of text to             
-- search in, we can return the frequency of occurrence of the term within the         
-- text.                                                                               
searchingFunc :: String -> [String] -> Int                                             
searchingFunc term                                                                     
    = length . filter predicate                                                        
  where                                                                                
    predicate = (==)term                                                               
  -- ^ we use function composition (.) to create a new function from two               
  -- existing ones:                                                                    
  --   filter (drop any elements of a list that don't satisfy                          
  --           our predicate)                                                          
  --   length: return the size of the list                                             

-- Here we build a wrapper-function that allows us to run our 'pure'            
-- searchingFunc on an input of the form returned by 'attemptOne'.                                                                 
runSearchingFunc :: String -> [[String]] -> [Int]                                      
runSearchingFunc term parsedData                                                       
  = map (searchingFunc term) parsedData                                                

-- Here's an example of piecing everything together with IO actions                    
main :: IO ()                                                                          
main = do                                                                              
  results <- attemptOne                                                                
  -- ^ run our attemptOne function (representing IO actions)                           
  -- and save the result                                                               
  let searchResults = runSearchingFunc "foo" results                                   
  -- ^ us a 'let' binding to state that searchResults is                               
  -- equivalent to running 'runSearchingFunc'                                          
  print searchResults                                                                  
  -- ^ run the IO action that prints searchResults                                     
  print (runSearchingFunc "foo" results)                                               
  -- ^ run the IO action that prints the 'definition'                                  
  -- of 'searchResults'; i.e. the above two IO actions                                 
  -- are equivalent.                                                                   
  return ()
  -- as before, lift a value into the encapsulating Monad;
  -- this time, we're lifting a value corresponding to 'null/void'.

要加载此代码,请将其保存到 .hs 文件中(我将其保存到“temp.hs”中),然后从 ghci 运行以下命令。注意:文件“f”包含一些输入单词:

*Main Text.Regex.Posix> :l temp.hs                               
[1 of 1] Compiling Main             ( temp.hs, interpreted )     
Ok, modules loaded: Main.                                        
*Main Text.Regex.Posix> main                                     
type text file                                                   
f                                                                
foo foos foor fo foo foo                                         

The data after running the regex: foofoosfoorfofoofoo            
[1,0,0,0,1,1]                                                    
[1,0,0,0,1,1]                                                    

这里发生了很多事情,从 do 表示法到 Monadic 操作,“let”绑定到纯函数/值和不纯函数/值之间的区别。我无法强调从一本好书中学习基础知识的价值!

I should start by iterating what everyone would (and should) say: Start with a book like Real World Haskell! That said, I'll post a quick walkthrough of code that compiles, and hopefully does something close to what you originally intended. Comments are inline, and hopefully should illustrate some of the shortcomings of your approach.

import Text.Regex.Posix                                                               

-- Let's start by wrapping your first attempt into a 'Monadic Action'
-- IO is a monad, and hence we can sequence 'actions' (read as: functions)
-- together using do-notation.                                                                 
attemptOne :: IO [[String]]
-- ^ type declaration of the function 'attemptOne'
-- read as: function returning value having type 'IO [[String]]'                                                            
attemptOne = do                                                                        
  putStrLn "type text file"                                                            
  filePath <- getLine                                                                  
  fileData <- readFile filePath                                                        
  putStrLn fileData                                                                    

  let parsed = fileData =~ "[^- \".,\n]+" :: [[String]]
  -- ^ this form of let syntax allows us to declare that
  -- 'wherever there is a use of the left-hand-side, we can
  -- substitute it for the right-hand-side and get equivalent
  -- results.                            
  putStrLn ("The data after running the regex: " ++ concatMap concat parsed)           

  return parsed                                      
  -- ^ return is a monadic action that 'lifts' a value
  -- into the encapsulating monad (in this case, the 'IO' Monad).                                  

-- Here we show that given a search term (a String), and a body of text to             
-- search in, we can return the frequency of occurrence of the term within the         
-- text.                                                                               
searchingFunc :: String -> [String] -> Int                                             
searchingFunc term                                                                     
    = length . filter predicate                                                        
  where                                                                                
    predicate = (==)term                                                               
  -- ^ we use function composition (.) to create a new function from two               
  -- existing ones:                                                                    
  --   filter (drop any elements of a list that don't satisfy                          
  --           our predicate)                                                          
  --   length: return the size of the list                                             

-- Here we build a wrapper-function that allows us to run our 'pure'            
-- searchingFunc on an input of the form returned by 'attemptOne'.                                                                 
runSearchingFunc :: String -> [[String]] -> [Int]                                      
runSearchingFunc term parsedData                                                       
  = map (searchingFunc term) parsedData                                                

-- Here's an example of piecing everything together with IO actions                    
main :: IO ()                                                                          
main = do                                                                              
  results <- attemptOne                                                                
  -- ^ run our attemptOne function (representing IO actions)                           
  -- and save the result                                                               
  let searchResults = runSearchingFunc "foo" results                                   
  -- ^ us a 'let' binding to state that searchResults is                               
  -- equivalent to running 'runSearchingFunc'                                          
  print searchResults                                                                  
  -- ^ run the IO action that prints searchResults                                     
  print (runSearchingFunc "foo" results)                                               
  -- ^ run the IO action that prints the 'definition'                                  
  -- of 'searchResults'; i.e. the above two IO actions                                 
  -- are equivalent.                                                                   
  return ()
  -- as before, lift a value into the encapsulating Monad;
  -- this time, we're lifting a value corresponding to 'null/void'.

To load this code, save it into a .hs file (I saved it into 'temp.hs'), and run the following from ghci. Note: the file 'f' contains a few input words:

*Main Text.Regex.Posix> :l temp.hs                               
[1 of 1] Compiling Main             ( temp.hs, interpreted )     
Ok, modules loaded: Main.                                        
*Main Text.Regex.Posix> main                                     
type text file                                                   
f                                                                
foo foos foor fo foo foo                                         

The data after running the regex: foofoosfoorfofoofoo            
[1,0,0,0,1,1]                                                    
[1,0,0,0,1,1]                                                    

There is a lot going on here, from do notation to Monadic actions, 'let' bindings to the distinction between pure and impure functions/values. I can't stress the value of learning the fundamentals from a good book!

暖心男生 2024-11-17 16:01:05

这是我的成果。它不进行任何错误检查并且尽可能基本。

import Text.Regex.Posix ((=~))
import Control.Monad (when)
import Text.Printf (printf)

-- Calculates the number of matching words
matchWord :: String -> String -> Int
matchWord file word = length . filter (== word) . concat $ file =~ "[^- \".,\n]+"

getInputFile :: IO String
getInputFile = do putStrLn "Enter the file to search through:"
                  path <- getLine
                  readFile path -- Attention! No error checking here

repl :: String -> IO ()
repl file = do putStrLn "Enter word to search for (empty for exit):"
               word <- getLine
               when (word /= "") $
                 do print $ matchWord file word
                    repl file

main :: IO ()
main = do file <- getInputFile
          repl file

Here is what I made of it. It doesn't does any error checking and is as basic as possible.

import Text.Regex.Posix ((=~))
import Control.Monad (when)
import Text.Printf (printf)

-- Calculates the number of matching words
matchWord :: String -> String -> Int
matchWord file word = length . filter (== word) . concat $ file =~ "[^- \".,\n]+"

getInputFile :: IO String
getInputFile = do putStrLn "Enter the file to search through:"
                  path <- getLine
                  readFile path -- Attention! No error checking here

repl :: String -> IO ()
repl file = do putStrLn "Enter word to search for (empty for exit):"
               word <- getLine
               when (word /= "") $
                 do print $ matchWord file word
                    repl file

main :: IO ()
main = do file <- getInputFile
          repl file
清君侧 2024-11-17 16:01:05

请一步步开始。 Haskell 中的 IO 是困难,因此您不应该从文件操作开始。我建议编写一个在给定的String上正常工作的函数。这样,您就可以学习语法、模式匹配、列表操作(映射、折叠)和递归,而不会被 do 表示法(这有点看起来命令式,但实际上并非如此)所分散。 t,确实需要更深入的理解)。

您应该查看 学习 Haskell现实世界的 Haskell 以获得良好的基础。你现在所做的只是在黑暗中绊倒——如果你学习的语言与你所知道的语言相似,那么这可能会起作用,但绝对不适用于 Haskell。

Please start step by step. IO in Haskell is hard, so you shouldn't start with file manipulation. I would suggest to write a function that works properly on a given String. That way you can learn about syntax, pattern matching, list manipulation (maps, folds) and recursion without beeing distracted by the do notation (which kinda looks imperative, but isn't, and really needs a deeper understanding).

You should check out Learn you a Haskell or Real World Haskell to get a sound foundation. What you do now is just stumbling in the dark - which may work if you learn languages that are similar to the ones you know, but definitely not for Haskell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文