2011-05-31 22 views
1

你好,我是做一些單詞搜索程序哈斯克爾單詞搜索程序開發

例如

當「的text.txt」文件包含「富FOOS福爾購買..富傻瓜」

和搜索

「foo」 的

然後只數2印刷

並再次並重新搜索

但我哈斯克爾初學者

我的代碼是在這裏

: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

我開始幾小時前哈斯克爾對不起

非常感謝您的閱讀!

編輯:這裏是原來的計劃代碼

謝謝!

#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) 
+1

我明白了,您在REPL中輸入了該代碼。 Haskell不是腳本語言(儘管可以用它來編寫腳本),通常編寫代碼的方法是將其放入一個後綴爲「.hs」的文件中。 – fuz 2011-05-31 14:00:34

+0

非常感謝您的建議。還要別的嗎? – 2011-05-31 14:03:06

+2

不要使用'data'作爲標識符。它是Haskell中引入新數據類型的保留字。 – fuz 2011-05-31 14:04:21

回答

2

這是我所做的。它沒有進行任何錯誤檢查,並且儘可能地基本。

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 
+0

它完美的作品謝謝! – 2011-06-01 00:16:22

2

請開始一步一步。 IO中的Haskell是,所以你不應該從文件操作開始。我會建議編寫一個在給定String上正常工作的函數。通過這種方式,您可以瞭解語法,模式匹配,列表操作(地圖,摺疊)和遞歸,而不會被注意力分散(這種類型看起來勢在必行,但不是,並且確實需要更深入的理解)。

你應該檢查出Learn you a HaskellReal World Haskell以獲得一個良好的基礎。你現在所做的只是在黑暗中蹣跚而行 - 如果你學習的語言與你所知道的類似,但是絕對不適用於Haskell,那麼可能會工作

4

我應該從迭代每個人都會(應該)說的話開始:從像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]              

有很多怎麼回事,從做記號,以一元行動,「讓」綁定到純和不純的功能/值之間的區別。我無法強調從一本好書學習基礎知識的價值!