2011-12-14 46 views
8

Chúng tôi có thể sử dụng loại từ đồng nghĩa cho định nghĩa hàm, ví dụ:Ví dụ về định nghĩa hàm trong hàm tạo dữ liệu của một kiểu mới

type FuncDef = Int -> Int -> Int 

Điều này tránh chúng tôi viết định nghĩa chức năng dài mọi lúc.

Sử dụng:

someFunc :: FuncDef -> Int 

Thay vì

someFunc :: (Int -> Int -> Int) -> Int 

đó là dễ đọc hơn và ít mã là tốt.

Loại dữ liệu đại số đơn giản là thẳng về phía trước và dễ dàng thực hiện đối sánh mẫu v.v., ví dụ:

data AType = X | Y | Z Int 
matchType :: AType -> Bool 
matchType X = .. 
matchType Y = .. 
matchType (Z _) = .. 

Khi tôi tìm hiểu thêm về các kiểu dữ liệu Haskell, tôi thấy chúng tôi có thể định nghĩa hàm trong hàm tạo dữ liệu khi xác định loại mới.

data MyType a b = X | Y (a -> b) 

Câu đố này hơi khó hiểu và không thấy nhiều ví dụ này. Theo một cách nào đó, ý tưởng về hàm bậc cao trong đó một hàm có thể lấy một hàm khác làm đối số tương tự như tình huống này, ngoại trừ ở đây nó áp dụng cho kiểu dữ liệu. Haskell wiki không nói nhiều về "định nghĩa kiểu dữ liệu bậc cao". Tôi nhận ra rằng tôi có thể nhận được tất cả các điều khoản này sai, vì vậy hãy sửa tôi và chỉ cho tôi đọc thêm. Tôi thực sự muốn thấy một cách sử dụng cụ thể về điều này. Cảm ơn!

matchMyType :: (MyType a b) -> Bool 
matchMyType X = .. 
matchMyType Y ?? = .. 
+8

Tôi nghĩ bạn có thể lo lắng quá nhiều! Như bạn nói, các hàm có thể được truyền dưới dạng đối số. Đó là vì các hàm không khác biệt với bất kỳ giá trị nào khác. Bạn có thể đặt chúng trong một kiểu dữ liệu và trích xuất chúng bằng cách khớp mẫu. Đó thực sự là tất cả để có nó. –

+0

cảm ơn +1, điều đó hoàn toàn có ý nghĩa với những gì bạn nói. bạn có thể cho tôi một ví dụ mà tôi muốn đặt một hàm trong cấu trúc dữ liệu thay vì chỉ các giá trị, ví dụ: số nguyên trong một cây? – vis

+1

Vâng, cách sử dụng thực tế nhất mà tôi có thể nghĩ đến đối với các kiểu dữ liệu có chứa các hàm phức tạp hơn và có lẽ sẽ chỉ mất tập trung từ vấn đề. Nếu bạn muốn một ví dụ chung chung, câu trả lời của dave4420 sẽ làm tốt. Nếu bạn muốn một cái gì đó khó khăn hơn để suy ngẫm, ví dụ bắt buộc có lẽ là [biến trạng thái đơn lẻ] (http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-State -Lazy.html # g: 2). –

Trả lời

11

Bạn có thể sử dụng loại mẫu này trong nhiều trường hợp. Ví dụ: nếu bạn muốn hàm chuyển đổi chuỗi theo nhiều cách khác nhau, bạn có thể có kiểu dữ liệu như thế này (Đây chỉ là ví dụ minh họa nguyên tắc - không viết mã như thế này!):

data StringTransformation = 
    -- | Doesn't transform the string at all 
    NoTransformation | 
    -- | Takes the string and generates a suffix that should be appended 
    Append (String -> String) | 
    -- | Takes the string and generates a prefix that should be prepended 
    Prepend (String -> String) | 
    -- | Takes the string and transforms it arbitrarily to a new string 
    Map (String -> String) 

Sau đó, một chương trình sử dụng hình thức này có thể trông giống như:

-- | Returns 'True' if the name is male 
isMaleName :: String -> Bool 
isMaleName = ... 

-- | Adds a title to a name, for example "John Smith" -> "Mr. John Smith" 
addTitle :: StringTransformation 
addTitle = 
    PrependTransformation $ \ name -> 
    if isMaleName name 
    then "Mr. " 
    else "Mrs. " 

-- Applies a string transformation to a 'String'. 
transformString :: StringTransformation -> String -> String 
transformString NoTransformation str = str 
transformString (Append f) str  = str ++ f str 
transformString (Prepend f) str  = f str ++ str 
transformString (Map f) str   = f str 
+0

+1 ví dụ đẹp :) sẽ chấp nhận câu trả lời nếu tôi không nhận được bất kỳ khác. – vis

4
data Thingy a b = A b 
       | B (a -> b) 

really :: Thingy a b -> a -> b 
really (A x) _ = x    -- x :: b 
really (B f) y = f y   -- f :: a -> b, y :: a, f y :: b 

Như C.A.McCann nói, không có gì đặc biệt về chức năng thực sự là.

+0

cảm ơn. tôi nghĩ thứ tự của các đối số trong khớp mẫu không đúng. tôi thấy cách làm khớp mẫu trên hàm trong kiểu dữ liệu, tương tự như bất kỳ hàm bậc cao bình thường nào. tại sao lưu trữ một chức năng trong loại? : s – vis

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