Tôi muốn viết một hàm mang theo cảPattern khớp nơi mô hình dựa trên một (chức năng) tham số
- một constructor giá trị cho một kiểu dữ liệu đại số nhất định, và
- một giá trị thực tế cùng loại đó,
và xác định liệu giá trị đã cho có được tạo từ "hàm tạo đã cho hay không. Khớp mẫu có vẻ giống như sự phù hợp tự nhiên cho điều này, nhưng mẫu phù hợp với sẽ phải là tham số hàm thay vì tên hàm dựng mã cứng.
Mã bên dưới là những gì tôi đã thử, nhưng GHC báo cáo lỗi phân tích cú pháp trên dòng được chỉ định.
Có cách nào để thực hiện việc này không?
data FooBar = Foo Int | Bar String
-- Imagine that these are useful functions.
processInt :: Int -> String
processInt = show
processString :: String -> String
processString = id
-- This should take one of the above functions and adapt it to operate on
-- FooBar values of compatible "type". Values that match the given FooBar
-- constructor should be "unwrapped" and passed to the given function.
typeCheck :: (a -> FooBar) -> (a -> String) -> (FooBar -> Maybe String)
typeCheck constructor func fooBar = case fooBar of
(constructor x) -> Just (func x) -- GHC says "Parse error in pattern: constructor"
_ -> Nothing
-- Define processing functions that operate on FooBars.
processFoo :: FooBar -> Maybe String
processFoo = typeCheck Foo processInt
processBar :: FooBar -> Maybe String
processBar = typeCheck Bar processString
Đây là máy tính RPN (chương trình thực hành) có thể có hỗn hợp các loại khác nhau (ví dụ: số và chuỗi) trên ngăn xếp. Hầu hết các chức năng hoạt động trên ngăn xếp sẽ bắt đầu bằng cách popping một số giá trị, kiểm tra xem chúng có đúng loại cho hoạt động hay không và báo cáo lỗi nếu không. Tôi đang cố gắng để loại trừ việc kiểm tra loại để tránh trùng lặp mã. – Wyzard
Ah! Sẽ dễ dàng hơn nhiều nếu bạn mã hóa các thẻ loại dưới dạng giá trị đơn giản (ví dụ: 'Giá trị' Int'), thay vì hàm khởi tạo. Đó là điều làm cho ví dụ của bạn trở nên phức tạp: việc khớp mẫu trên các hàm chỉ là khó khăn. –
Cảm ơn, tôi sẽ xem xét sử dụng thẻ loại số thay thế. Vì tập hợp các kiểu của tôi tương đối hạn chế, tôi cũng có thể tạo ra một họ các hàm như 'typeCheckInt',' typeCheckString', vv với hàm tạo thích hợp được mã hóa cứng trong mỗi loại.Vì đây là một chương trình thực hành, tôi nghĩ tôi sẽ thử một chút khó khăn hơn, nhưng có vẻ như tôi đã bị cắn nhiều hơn tôi có thể nhai. Tôi đã quen thuộc với generics trong ngữ cảnh của C++ và Java, nhưng không phải trong ngữ cảnh của Haskell. – Wyzard