2017-02-05 11 views
1

Я иду через these Haskell «промежуточных» упражнений, я сделал следующие случаи:Оператор стрелок в объявлениях экземпляров functor?

class Fluffy f where 
    furry :: (a -> b) -> f a -> f b 

instance Fluffy [] where 
    furry f [] = [] 

instance Fluffy Maybe where 
    furry f (Just e) = Just (f e) 
    furry f (Nothing) = Nothing 

Однако синтаксис третий вопрос поставлен в тупик меня:

instance Fluffy ((->) t) where 
    ... 

Я читал на стрелке, а также прочитать ответ this, в котором объясняется роль (->) в экземпляре Monad. Однако я не совсем понимаю, как работает (->) в контексте функторов?

ответ

9

Мы имеем:

class Fluffy f where 
    furry :: (a -> b) -> f a -> f b 

Мы хотим, чтобы определить:

instance Fluffy ((->) t) where 
    furry = ... 

Это означает, что в приведенном выше случае furry должен иметь тип (a -> b) -> f a -> f b где f является ((->) t), или другими словами:

furry :: (a -> b) -> ((->) t) a -> ((->) t) b 

Подобно тому, как ((+) 2) 3 такая же, как 2 + 3, ((->) X) Y такая же, как X -> Y (это приложение кэрри оператор и он работает даже на уровне типа):

furry :: (a -> b) -> (t -> a) -> (t -> b) 

Мы можем прочитать выше подпись как "заданной функции от a до b и от t до a, вернуть функцию от t до b ".

Теперь вам просто нужно его реализовать. :-)

2

Определим экземпляр Functor как таковой:

instance Functor ((->) a) where 
    fmap f g = \a -> f (g a) 
    -- Pointfree definition: fmap = (.) 

То есть, то (->) функтор сравним с контейнером, который только может быть «открыт», получив некоторое значение типа a и «открыть» контейнер с ним. Любой fmap затем просто меняет значение после того, как мы «откроем» контейнер. Т.е.: составные функции.

Это немного похоже на функтор Maybe, в котором я могу применить функцию к значению, если он существует, но для функтора (->). Я делаю это, прежде чем мы узнаем, что это такое.

Но помните, что все монады функтора, так как мы могли бы просто определить fmap, как так:

fmap f m = m >>= (\a -> return (f a)) 

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