2012-04-21 24 views
8

Có thể viết một hàm isFunc :: a -> Bool để xác định xem một giá trị tùy ý là một chức năng (dưới mọi hình thức) sao choXác định xem một giá trị là một chức năng trong Haskell

foo :: Int -> Int 
bar :: Char -> Char -> Char  

> isFunc foo 
True 
> isFunc bar 
True 
> isFunc 3 
False 
> isFunc 'a' 
False 

Tôi đang sử dụng Data.Dynamic vì vậy tôi không thể xác định loại trước.

+3

'isFunc' không phải là một câu hỏi cũng như hình thành để hỏi trong sự hiện diện của đa hình. Tôi có một thứ kiểu 'a'; nó có phải là một chức năng hay không? Câu trả lời là không xác định cho đến khi tôi đã biến 'a' thành kiểu đơn hình, vì cho đến lúc đó tôi có thể chọn, ví dụ,' a ~ Int' hoặc 'a ~ Int -> Int'. Ví dụ 'isFunc 3' của bạn có chính xác vấn đề này, và thậm chí bạn có thể không nhận ra; làm thế nào để bạn biết '3' không phải là một chức năng? –

Trả lời

10

Tham số nói không. Các chức năng duy nhất của loại

a -> Bool 

là các hàm liên tục.

Tuy nhiên, với một chút đa hình ad-hoc và sự gan dạ hơn chút, bạn có thể làm điều này:

{-# LANGUAGE OverlappingInstances, FlexibleInstances #-} 

class Sick x where 
    isFunc :: x -> Bool 

instance Sick (a -> b) where 
    isFunc _ = True 

instance Sick x where 
    isFunc _ = False 

và sau đó có vẻ như bạn có

*Sick> isFunc 3 
False 
*Sick> isFunc id 
True 

Nhưng nó không có vẻ như một điều kỳ lạ để làm. Sử dụng kết quả Bool cho bạn là gì?

+0

Tôi đang lập bản đồ trên danh sách các giá trị được nhập động và áp dụng x cho các giá trị là hàm. – jhibberd

+1

Tôi không tin rằng cách tiếp cận này sẽ thực sự làm việc cho vấn đề đó - hoặc, thẳng thắn, cách tiếp cận _any_ đó sẽ làm việc cho vấn đề đó, trong Haskell. Các cá thể Typeclass trong Haskell luôn được giải quyết tại thời gian biên dịch, không phải thời gian chạy, và tình huống mà bạn mô tả có vẻ như yêu cầu độ phân giải thời gian chạy. –

11

Bạn đang yêu cầu gì và bạn cần làm gì với Data.Dynamic có vẻ là những thứ khác nhau. Bạn cần biết loại giá trị chính xác trước khi giải nén nó với fromDyn/fromDynamic. Để xác định xem Dynamic chứa một giá trị chức năng bạn cần phải phân tích TypeRep:

isFuncDynamic x = typeRepTyCon (dynTypeRep x) == typeRepTyCon (typeOf2 id) 

(Hãy tha thứ cho tôi nếu đây không phải là việc thực hiện ngắn gọn nhất.)

+0

Cảm ơn. Chức năng này (mặc dù được xây dựng bằng tay) chỉ là những gì tôi đang tìm kiếm. – jhibberd

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