2.4.2 wxHaskell
wxHaskell является портативной GUI библиотекой для Haskell, построенной на wxWidgets. Очень часто используются для создания графического интерфейса на функциональном языке.
wxHaskell является графической библиотекой среднего уровня. От wxHaskell есть производные библиотеки высокого уровня:
wxFruit
Phooey
В отличие от wxHaskell, на высоком уровне GUI эти библиотеки реализованы на Gtk2Hs, которая основана на gtk2.
Все вышеупомянутые GUI библиотеки являются экспериментальными, с использованием современных математических понятий в их подходе.
3. Анализ задачи
icqTest :: String -> Bool
По наличию @ в строке устанавливает ее принадлежность к полю e-mail.
pare :: [String] -> [(String,String)]
Из входной строки формирует список пар ICQ и e-mail.
pare2 :: [String] -> [(String,String)]
Из входной строки формирует список пар e-mail и ИОФ
comp :: String -> [(String,String)] -> String
Функция алгоритма поиска для получения ИОФ контакта
f :: [(String,String)] -> [(String,String)] -> String
Функция алгоритма поиска, формирует структуру таблицы html документа.
outFile :: String -> String -> String -> IO()
Функция, выводящая результаты поиска в файл и формирующая html документ
main :: IO ()
Входная точка в программу, формирует графический интерфейс пользователя.
4. Программная реализация
import Graphics.UI.WX
import Graphics.UI.WXCore
import System
import Char ( toUpper)
import IO
--test for e-mail? or ICQ?
icqTest :: String -> Bool
icqTest [] = False
icqTest (x:xs) = if x=='@' then True else icqTest xs
--pare ICQ and E-mail
pare :: [String] -> [(String,String)]
pare [] = []
pare [x] = (x," "):[]
pare (x:xs) = if icqTest (head xs)==False then (x,head xs):[]++pare (tail xs) else (x," "):[]++pare xs
--pare E-mail and IOF
pare2 :: [String] -> [(String,String)]
pare2 [] = []
pare2 (x:xs) = if icqTest (head xs)==False then (if icqTest (head(tail xs))==False then (x++" "++(head xs)++" "++(head (tail xs)),head(tail(tail xs))):[]++pare2 (tail(tail(tail xs))) else (x++" "++head xs,head(tail xs)):[]++pare2 (tail(tail xs)) ) else (x,head xs):[]++pare2 (tail xs)
--compare E-mail and return IOF
comp :: String -> [(String,String)] -> String
comp _ [("","")] = []
comp [] _ = []
comp x (y:ys) = if x==snd y then fst y else comp x ys
--compare pares and build html table
f :: [(String,String)] -> [(String,String)] -> String
f [([],[])] _ = ""
f (x:xs) (y:ys) = (("<TR>"++"\n"++"<TD>"++comp (fst x) (y:ys)) ++"</TD>"++"\n"++"<TD>"++ snd x ++ "</TD>" ++"\n"++"<TD>"++"<a href="++"\""++"mailto:"++ fst x ++"\""++">"++fst x++"</a>"++"</TD>"++"\n"++"</TR>"++"\n") ++ (if null xs then "" else f xs (y:ys))
--write html code in out File
outFile :: String -> String -> String -> IO()
outFile x y z = do s <- readFile x; d <- readFile y;writeFile z "<HTML> \n <Body bgcolor = floralwhite> \n <TABLE border=5 alight = center> \n <TR> <TH> FIO </TH> \n <TH> ICQ </TH> \n <TH> E-mail </TH> \n </TR> \n"; appendFile z (f (pare(words s))(pare2(words d)));appendFile z "</TABLE> \n </BODY> \n </HTML>"
--GUI mode
main :: IO ()
main = start gui
gui :: IO ()
gui
= do -- main gui elements: frame, panel, text control, and the notebook
f <- frame [text := "Controls"]
p <- panel f []
nb <- notebook p []
textlog <- textCtrl p [enabled := False, wrap := WrapNone]
-- use text control as logger
textCtrlMakeLogActiveTarget textlog
logMessage "logging enabled"
-- set f [on closing :~ \prev -> do logSetActiveTarget oldlog; logDelete log; prev]
-- first page
p1 <- panel nb []
--textBoxes
txt1 <- textEntry p1 [alignment := AlignLeft, text := "icq file name"]
txt2 <- textEntry p1 [alignment := AlignLeft, text := "e-mail file name"]
txt3 <- textEntry p1 [alignment := AlignLeft, text := "out file name"]
--buttons
ok <- button p1 [text := ">>", on command := do f1 <- get txt1 text;f2 <- get txt2 text;f3 <- get txt3 text; logMessage f1 ;logMessage f2;logMessage f3;outFile f1 f2 f3;]
quit <- button p1 [text := "Close", on command := close f]
-- specify layout
set f [layout :=
container p $
column 0
[ tabs nb
[tab "Sort Contakt List" $
container p1 $ margin 10 $ column 5 [hstretch $ widget txt1,hstretch $ widget txt2,hstretch $ widget txt3,row 5 [floatRight $ widget ok,floatLeft $ widget quit]]
]
, hfill $ minsize (sz 20 80) $ widget textlog
]
, clientSize := sz 400 300 ]
return ()
5. Тестирование программы
Изначальный вид приложения при запуске:
Рис.5.1
Введем Пути файлов в поля ввода:
Рис.5.2
После счелкаем кнопку >> и получаем html документ:
Заключение
В результате проделанной работы было получено приложение, сортирующее список контактов из файлов по ключевому полю e-mail. Для решения поставленной задачи был разработан и реализован алгоритм поиска для файлов с информацией, хранимой в заданном формате. Для реализации приложения была использована среда разработки языка Haskell-98 GHCi 6.10.1.
Список используемой литературы
1. Н.А. Роганова «Функциональное программирование»
2. Курс лекций по функциональному программированию
3. www.intuit.ru/department/pl/haskel98/6/
4. www.rsdn.ru/article/haskell/haskell_part1.xml
5. http://wxhaskell.sourceforge.net/
6. http://en.wikipedia.org/wiki/WxWidgets
0 комментариев