2011-10-18 36 views
12

Đây là chương trình haskell đầu tiên của tôi! "wordCount" lấy một danh sách các từ và trả về một tuple với mỗi từ không phân biệt dạng chữ được ghép với số lượng sử dụng của nó. Bất kỳ đề xuất cải thiện về khả năng đọc mã hoặc hiệu suất?Số từ đơn giản trong haskell

import List; 
import Char; 
uniqueCountIn ns xs = map (\x -> length (filter (==x) xs)) ns 
nubl (xs) = nub (map (map toLower) xs) -- to lowercase 
wordCount ws = zip ns (uniqueCountIn ns ws) 
    where ns = nubl ws 

Trả lời

24

Chúc mừng chương trình đầu tiên của bạn!

Để làm sạch: mất dấu chấm phẩy. Thay vào đó, hãy sử dụng tên mô-đun phân cấp mới (Data.List, Data.Char). Thêm chữ ký loại. Khi bạn cảm thấy thoải mái hơn với thành phần hàm, eta sẽ định nghĩa các định nghĩa hàm của bạn (loại bỏ các đối số bên phải). ví dụ.

nubl :: [String] -> [String] 
nubl = nub . map (map toLower) 

Nếu bạn muốn được thực sự chặt chẽ, sử dụng danh sách nhập khẩu rõ ràng:

import Data.List (nub) 
import Data.Char (toLower) 

Đối với hiệu suất: sử dụng một Data.Map để lưu trữ các hiệp hội thay vì nubfilter. Cụ thể, xem fromListWithtoList. Sử dụng các chức năng đó, bạn có thể đơn giản hóa việc triển khai và cải thiện hiệu suất cùng một lúc.

+0

Cảm ơn, tối nay tôi sẽ khắc phục các đề xuất đó. Bạn kiếm được nghiệp đó :) –

2

Thêm chữ ký loại của các chức năng thực sự sẽ hữu ích.

6

Bạn luôn có thể hỏi các nhà phát triển có kinh nghiệm nhiều hơn về phản hồi. Tuy nhiên, bạn có thể sử dụng hlint để nhận phản hồi về một số vấn đề quy mô nhỏ. Nó sẽ cho bạn biết về nhập khẩu phân cấp, dấu ngoặc đơn không cần thiết, các hàm bậc cao thay thế, v.v.

Về hàm, nub1. Nếu bạn không làm theo lời khuyên của luqui để loại bỏ các tham số hoàn toàn được nêu ra, tôi ít nhất sẽ loại bỏ dấu ngoặc đơn xung quanh xs ở phía bên phải của phương trình.

+0

Tôi đoán rằng bạn có nghĩa là bên trái thay vì phải. –

+0

vâng, bạn nói đúng. – jmg

15

Một trong những cách để cải thiện khả năng đọc là cố gắng làm quen với các chức năng chuẩn. Hoogle là một trong những công cụ mà bộ Haskell ngoài các phần còn lại của thế giới;)

import Data.Char (toLower) 
import Data.List (sort, group) 
import Control.Arrow ((&&&)) 

wordCount :: String -> [(String, Int)] 
wordCount = map (head &&& length) . group . sort . words . map toLower 

EDIT: Giải thích: Vì vậy, bạn nghĩ về nó như một chuỗi các ánh xạ:

  • (map toLower) :: String -> String lowercases toàn bộ văn bản, vì mục đích của trường hợp không nhạy cảm
  • words :: String -> [String] chia một đoạn văn bản thành các từ
  • sort :: Ord a => [a] -> [a] phân loại
  • group :: Eq a => [a] -> [[a]] tập hợp các yếu tố identicial trong một danh sách, ví dụ, group [1,1,2,3,3] ->[[1,1],[2],[3,3]]
  • &&& :: (a -> b) -> (a -> c) -> (a -> (b, c)) áp dụng hai chức năng trên cùng một mảnh của dữ liệu, sau đó trả về các tuple của kết quả. Ví dụ: (head &&& length) ["word","word","word"] ->("word", 3) (trên thực tế &&& là tổng quát hơn một chút, nhưng lời giải thích đơn giản hóa việc cho ví dụ này)

EDIT: Hoặc thực sự, tìm kiếm gói "MultiSet" trên Hackage.

+3

triển khai chức năng trừu tượng không phù hợp với người mới bắt đầu (ví dụ: '&&&'), cũng không có giải thích. -1 – luqui

+2

OK, hãy để tôi thêm giải thích T_T – Phil

+4

tốt hơn nhiều. Tôi thích thứ tự của chuỗi và bạn đã bao gồm chữ ký kiểu để chúng tôi có thể xem dữ liệu biến đổi như thế nào trên đường đi qua chuỗi. – luqui

Các vấn đề liên quan