Tất cả các Text.Regex.*
module sử dụng nhiều của typeclasses, đó là có cho khả năng mở rộng và "quá tải" hành vi giống như, nhưng làm cho việc sử dụng ít obvio chúng tôi chỉ nhìn thấy các loại.
Bây giờ, có thể bạn đã bắt đầu từ trình kết hợp cơ bản =~
.
(=~) ::
(RegexMaker Regex CompOption ExecOption source
, RegexContext Regex source1 target)
=> source1 -> source -> target
(=~~) ::
(RegexMaker Regex CompOption ExecOption source
, RegexContext Regex source1 target, Monad m)
=> source1 -> source -> m target
Để sử dụng =~
, thì phải có một thể hiện của RegexMaker ...
cho LHS, và RegexContext ...
cho RHS và kết quả.
class RegexOptions regex compOpt execOpt | ...
| regex -> compOpt execOpt
, compOpt -> regex execOpt
, execOpt -> regex compOpt
class RegexOptions regex compOpt execOpt
=> RegexMaker regex compOpt execOpt source
| regex -> compOpt execOpt
, compOpt -> regex execOpt
, execOpt -> regex compOpt
where
makeRegex :: source -> regex
makeRegexOpts :: compOpt -> execOpt -> source -> regex
Một thể hiện giá trị của tất cả các lớp này (ví dụ, regex=Regex
, compOpt=CompOption
, execOpt=ExecOption
và source=String
) có nghĩa là nó có thể biên dịch một regex
với compOpt,execOpt
tùy chọn từ một số hình thức source
. (Ngoài ra, đưa ra một số regex
loại, có đúng một compOpt,execOpt
bộ mà đi cùng với nó. Rất nhiều source
loại khác nhau là okay, mặc dù.)
class Extract source
class Extract source
=> RegexLike regex source
class RegexLike regex source
=> RegexContext regex source target
where
match :: regex -> source -> target
matchM :: Monad m => regex -> source -> m target
Một thể hiện giá trị của tất cả các lớp này (ví dụ, regex=Regex
, source=String
, target=Bool
) có nghĩa là có thể khớp với một số source
và regex
để mang lại một số target
. (Khác hợp lệ target
s cho những cụ regex
và source
là Int
, MatchResult String
, MatchArray
, vv)
Đặt này lại với nhau và nó khá rõ ràng rằng =~
và =~~
chỉ đơn giản là chức năng thuận tiện
source1 =~ source
= match (makeRegex source) source1
source1 =~~ source
= matchM (makeRegex source) source1
và cũng là =~
và =~~
không có chỗ để chuyển các tùy chọn khác nhau tới makeRegexOpts
.
Bạn có thể làm của riêng
(=~+) ::
(RegexMaker regex compOpt execOpt source
, RegexContext regex source1 target)
=> source1 -> (source, compOpt, execOpt) -> target
source1 =~+ (source, compOpt, execOpt)
= match (makeRegexOpts compOpt execOpt source) source1
(=~~+) ::
(RegexMaker regex compOpt execOpt source
, RegexContext regex source1 target, Monad m)
=> source1 -> (source, compOpt, execOpt) -> m target
source1 =~~+ (source, compOpt, execOpt)
= matchM (makeRegexOpts compOpt execOpt source) source1
mà có thể được sử dụng như
"string" =~+ ("regex", CompCaseless + compUTF8, execBlank) :: Bool
hoặc ghi đè =~
và =~~
với các phương pháp có thể chấp nhận tùy chọn
import Text.Regex.PCRE hiding ((=~), (=~~))
class RegexSourceLike regex source
where
makeRegexWith source :: source -> regex
instance RegexMaker regex compOpt execOpt source
=> RegexSourceLike regex source
where
makeRegexWith = makeRegex
instance RegexMaker regex compOpt execOpt source
=> RegexSourceLike regex (source, compOpt, execOpt)
where
makeRegexWith (source, compOpt, execOpt)
= makeRegexOpts compOpt execOpt source
source1 =~ source
= match (makeRegexWith source) source1
source1 =~~ source
= matchM (makeRegexWith source) source1
hoặc bạn chỉ có thể sử dụng match
, makeRegexOpts
, v.v. trực tiếp khi cần.
Ah, có vẻ như tôi đã bị đánh bại với giải pháp. Đó là những gì tôi nhận được để viết tất cả các loại công cụ không cần thiết: -/ – ephemient
Ah, tôi cảm thấy một chút tội lỗi bây giờ, bạn chắc chắn cung cấp một cái nhìn tổng quan hơn toàn diện! Tôi thích bạn gợi ý cho (= ~ +) bằng cách này. – dukedave
đó là một câu trả lời rất đầy đủ và toàn diện thực sự, tôi muốn thưởng cho những nỗ lực, nhưng tôi không biết nếu đó là thực tế phổ biến để chuyển "câu trả lời được chấp nhận"? dù sao, tôi mới đến Haskell, và câu trả lời này thực sự đã giúp tôi hiểu một số nguyên tắc thông minh của ngôn ngữ (cũng có ít lỗi đánh máy lúc đầu bạn viết = ~ thay vì = ~~) –