2009-10-21 36 views
16

Giả sử tôi muốn tạo một trường hợp đặc biệt cho hàm phù hợp với chuỗi bắt đầu bằng ký tự 'Z'. Tôi có thể dễ dàng thực hiện việc đó bằng cách sử dụng mẫu phù hợp bằng cách thực hiện một số việc như sau:Tiền tố chuỗi đối sánh mẫu trong Haskell

myfunc ('Z' : restOfString) = -- do something special 
myfunc s = -- do the default case here 

Nhưng điều gì xảy ra nếu tôi muốn khớp với các chuỗi có tiền tố dài hơn? Nói rằng tôi muốn có một trường hợp đặc biệt cho các chuỗi bắt đầu bằng từ "nướng bánh". Cách tốt nhất để viết một mẫu để phù hợp với một chuỗi như thế nào?

+0

Ngoại tuyến có vẻ khá đơn giản để viết và gọi Mẫu Haskell để đạt được hiệu quả mong muốn. Tuy nhiên, tôi không đủ của một người TH để chắc chắn. –

+0

Thật không may, GHC không thực hiện ghép mẫu (theo như tôi biết, rõ ràng nó thực sự khó khăn), vì vậy điều này là không thể. – ephemient

Trả lời

29
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ... 

Sử dụng kết hợp mẫu bình thường hoạt động, nhưng khó chịu khi chuỗi tiền tố dài hơn.

{-# LANGUAGE PatternGuards #-} 
import Data.List 
myFunc string | Just restOfString <- stripPrefix "toaster" string = 
    -- do something special 
myFunc string = -- do the default case here 

Sử dụng chức năng thư viện thay vì đối sánh mẫu dễ đọc và viết dễ hơn.

{-# LANGUAGE ViewPatterns #-} 
import Data.List 
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special 
myFunc string = -- do the default case here 

Mở rộng cú pháp GHC 6.10 làm cho việc sử dụng này trở nên tự nhiên hơn.


Tất nhiên, hai sau hoàn toàn tương đương và chúng ta có thể làm (lộn xộn) mà không có bất kỳ đường nào.

import Data.List 
myFunc string = 
    if restIsJust 
     then -- do something special 
     else -- do the default case here 
    where 
    (restIsJust, restOfString) = 
     case stripPrefix "toaster" string of 
      Just something -> (True, something) 
      Nothing -> (False, undefined) 

Các tiện ích mở rộng cú pháp này có nghĩa là làm cho cuộc sống dễ dàng hơn đối với chúng tôi.

3
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString) 

Theo như tôi biết, không có cú pháp ngắn gọn hơn.

Bạn cũng có thể kiểm tra xem chuỗi có bắt đầu bằng lò nướng trong điều khoản bảo vệ hay if bên trong thân chức năng.

8
import Data.List 

myFunc str | "toaster" `isPrefixOf` str = something restOfString 
      | otherwise = somethingElse 
    where Just restOfString = stripPrefix "toaster" str 
+2

Tôi đã suy nghĩ về một cái gì đó như thế này đầu tiên, nhưng có vẻ ngớ ngẩn khi phải viết '' lò nướng bánh '' hai lần. – ephemient

3
myFunc str = 
    case stripPrefix "toaster" str of 
    Just restOfString -> something restOfString 
    Nothing -> somethingElse 

Đây là lý do stripPrefix trả về loại Có thể.