Вы можете сделать это просто для проверки элемента, если это первый дочерний элемент: $(this).is(':first-child')
. Другие селекторы, такие как :last-child
, тоже будут работать.
Определение $ равно
f $ x = f x
Давайте полностью заключим в скобки вашу функцию:
every f xs = (liftM (all id)) (sequence ((map f) xs))
и вашу каррированную версию:
every = (liftM (all id)) (sequence map)
Как вы заметил, они не идентичны. Вы можете отбрасывать конечные аргументы функции только тогда, когда они применяются в последнюю очередь. Например,
f x = g c x
на самом деле является
f x = (g c) x
, и приложение (gc) к x идет последним, поэтому вы можете написать
f = g c
. Один из паттернов с оператором приложения $ заключается в том, что он часто становится оператором композиции. в безбалльных версиях. Это потому, что
f $ g $ x
эквивалентно
(f . g) $ x
. Например,
every f xs = liftM (all id) $ sequence $ map f xs
может стать
every f xs = (liftM (all id) . sequence . map f) xs
, в этот момент вы можете отбросить xs:
every f = liftM (all id) . sequence . map f
Устранение аргумента f сложнее, потому что он применяется перед оператором композиции . Позволять' s используйте определение точки из http://www.haskell.org/haskellwiki/Pointfree :
dot = ((.) . (.))
С точками это
(f `dot` g) x = f . g x
, и это именно то, что нам нужно, чтобы все точки были полностью заполнены. бесплатно:
every = (liftM (all id) . sequence) `dot` map
К сожалению, из-за ограничений в системе типов Haskell для этого требуется явная сигнатура типа:
every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool