2015-03-13 3 views
4

Для списка, почему right apply (*>) ведет себя как повторяющийся и добавляет второй аргумент n раз, где n - это длина первого аргумента?Понимание права Применить

ghci> [1,2,3] *> [4,5] 
[4,5,4,5,4,5] 
+0

Вы уверены, его не '' >>? – thefourtheye

+2

@thefourtheye '*>' is '>>', если рассматриваемая аппликация также является монадой. – Cubic

+0

@Cubic Спасибо :) – thefourtheye

ответ

7

определен Оператор *>, по умолчанию, так как

xs *> ys = id <$ xs <*> ys 

, который, в свою очередь переводит, по умолчанию, чтобы

const id <$> xs <*> ys 

То есть, он заменяет каждый элемент xs с id, чтобы получить xs', а затем вычисляет xs' <*> ys. [] - пример Monad, где (=<<) = concatMap. Один из законов Applicative выкладывают отношения между Applicative и Monad случаями:

pure = return 
fs <*> as = fs `ap` as = fs >>= \f -> as >>= \a -> f a 

Для списков, это

fs <*> as = [f a | f <- fs, a <- as] 

*> Так для списков, в конечном счете определяется экземпляром Monad.

Обратите внимание, что есть еще один очень разумный Applicative экземпляр списков, который доступен через Newtype в Control.Applicative:

newtype ZipList a = ZipList [a] 
instance Applicative ZipList where 
    pure = repeat 
    (<*>) = zipWith ($) 
+5

В конце концов, эффект состоит в том, что каждый элемент '[1,2,3]' заменяется на '[4,5]', давая '[[4,5], [4, 5], [4,5]] ', который затем выравнивается с' concat' в '[4,5,4,5,4,5]'. Если вы определяете это самостоятельно как 'xs *> ys = concat (map (const ys) xs)', вы можете показать, что это эквивалентно данному определению '(*>)', а также '(>>) '. –

+0

@ ReinHenrichs, мне нужно закончить это правильно и переделать некоторые вещи, но сейчас я чувствую себя странно головокружительно, так что трудно сосредоточиться. Если вы хотите сделать последний шаг или два из '<*>' '' '>', перейдите и отредактируйте. – dfeuer

+0

Я пробовал это, и это было трудно, поэтому я остановился, когда увидел ваш ответ. : D Это довольно крутой путь. –