2015-07-05 11 views
8

tôi nhìn vào tài liệu cho Data.Traversable và đã xem qua fmapDefault - https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base/Data-Traversable.html#g:3Điểm 'fmapDefault' trong 'Data.Traversable' là gì?

fmapDefault :: Traversable t => (a -> b) -> t a -> t b 

Các trạng thái tài liệu -

Chức năng này có thể được sử dụng như một giá trị cho fmap trong một trường hợp functor, miễn là giao điểm được xác định.

Vì vậy, có lẽ nó có thể được sử dụng để lấy số fmap cho ví dụ Traversable. Tuy nhiên, TraversableFunctor là một siêu lớp.

class (Functor t, Foldable t) => Traversable t where 
    ... 

Vì vậy, bạn không thể xác định một trường hợp Traversable mà không quy định trường hợp Functor đầu tiên! Và bất cứ nơi nào bạn có Traversable, bạn có quyền truy cập vào một fmap, tương đương với (và có lẽ hiệu quả hơn) fmapDefault.

Vì vậy, nơi nào người ta sẽ sử dụng fmapDefault, thay vì nhiều người quen thuộc hơn fmap?

+2

"Bạn không thể xác định cá thể' Traversable' mà không định nghĩa cá thể 'Functor' trước!" Vâng, "đầu tiên" là một thuật ngữ khá ... –

+0

Vâng, đó là một chút của một fart não. Giống như giả định 1 đến trước 2, do năm tính theo thủ tục từ 0-10. Và thế thì bạn xem xét câu hỏi - điều gì đến trước, '-1' hay '-2', và được chứng ngộ. –

Trả lời

11

Nó cho phép bạn viết

data Foo a = ... 

instance Functor Foo where -- we do define the functor instance, but we “cheat” 
    fmap = fmapDefault  -- by using `Traversable` in its implementation! 

instance Traversable Foo where 
    traverse = ...   -- only do this manually. 

Điều đó nói rằng, tôi không nghĩ rằng đây là thực sự hợp lý. Các cá thể Functor thường không dễ dàng thực hiện bằng tay, và việc thực hiện rõ ràng sẽ thực sự có hiệu quả hơn một số xuất phát từ Traversable. Thông thường, trường hợp trên thực tế có thể được tạo tự động:

{-# LANGUAGE DeriveFunctor #-} 

data Foo a = ... 
     deriving (Functor) 
+0

* Thông thường, trường hợp trên thực tế có thể được tạo tự động [...] * Không phải luôn luôn như vậy? – Jubobs

+3

@Jubobs: không hoàn toàn, đối với một số GADT tôi đã nhận được lỗi về lòng tốt với 'DeriveFunctor'. Nhưng có thể đây chỉ là một lỗi trong GHC-7.8. – leftaroundabout

+2

Chết tiệt, tôi đã vô tình giả định rằng các định nghĩa 'phân lớp' không thể tham chiếu đến các định nghĩa 'siêu lớp'. Rõ ràng đó là một phần nào đó của một yêu cầu tùy ý trong nhận thức. Đó là những gì bạn nhận được khi bạn phải sử dụng một nửa thời gian. –