2015-07-05 4 views
8

Я смотрю на документацию для Data.Traversable и наткнулся на fmapDefault - https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base/Data-Traversable.html#g:3Что такое «fmapDefault» в «Data.Traversable»?

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

-сдаточной документации говорится, что -

Эта функция может быть использована в качестве значения БПМЖ в экземпляре Functor, при условии, что траверс определен.

Так, предположительно это может быть использовано для выведения fmap для Traversable экземпляра. Однако Traversable имеет Functor как суперкласс.

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

Таким образом, вы не можете определить Traversable экземпляр без определения экземпляра Functor первым! И где бы вы ни находились Traversable, у вас есть доступ к fmap, что эквивалентно (и, возможно, более эффективно, чем) fmapDefault.

Итак, где бы вы использовали fmapDefault, а не намного знакомы fmap?

+2

«Вы не можете определить экземпляр« Traversable », не указав сначала экземпляр« Functor »! Ну, «первый» - это такой белковый термин ... –

+0

Да, это был немного мозговой пердит. Как и предполагалось, 1 приходит до 2, из-за многолетнего подсчета процессуально от 0 до 10. И тогда вы рассматриваете вопрос - что на первом месте, «-1» или «-2», и просвещены. –

ответ

11

Это позволяет писать

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. 

То есть, я не думаю, что это действительно разумно. Экземпляры Functor обычно тривиальны для выполнения вручную, и очевидная реализация, скорее всего, будет более эффективной, чем производная от Traversable. Обычно экземпляр может быть создан автоматически:

{-# LANGUAGE DeriveFunctor #-} 

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

* Обычно экземпляр может быть создан автоматически [...] * Не так ли? – Jubobs

+3

@Jubobs: не совсем, для некоторых GADT я получил ошибки о доброжелательности с 'DeriveFunctor'. Но, возможно, это была просто ошибка в GHC-7.8. – leftaroundabout

+2

Черт, я подсознательно предположил, что определения подкласса не могут относиться к определениям суперкласса. Очевидно, что это случайное требование в ретроспективе. Это то, что вы получаете, когда вам приходится использовать половину времени. –

 Смежные вопросы

  • Нет связанных вопросов^_^