Я прохожу этот курс.
Есть раздел для Applicative
, и меня просят реализовать функцию со следующим поведением и набрать
-- | Filter a list with a predicate that produces an effect.
--
-- >>> filtering (ExactlyOne . even) (4 :. 5 :. 6 :. Nil)
-- ExactlyOne [4,6]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. Nil)
-- Full [4,5,6]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. 7 :. 8 :. 9 :. Nil)
-- Full [4,5,6,7]
--
-- >>> filtering (\a -> if a > 13 then Empty else Full (a <= 7)) (4 :. 5 :. 6 :. 13 :. 14 :. Nil)
-- Empty
--
-- >>> filtering (>) (4 :. 5 :. 6 :. 7 :. 8 :. 9 :. 10 :. 11 :. 12 :. Nil) 8
-- [9,10,11,12]
--
-- >>> filtering (const $ True :. True :. Nil) (1 :. 2 :. 3 :. Nil)
-- [[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
filtering :: Applicative f => (a -> f Bool) -> List a -> f (List a)
Я предложил следующую реализацию, которая удовлетворяет всем требованиям
filtering f as =
let x = sequence (f `map` as)
y = zip as <$> x
z = filter snd <$> y
in map fst <$> z
но мне это кажется немного "круглым", и я не могу придумать более прямой способ сделать это.
Примечание: я расширился до x, y, z
, потому что это облегчает (для меня) следить за тем, что происходит, и хотя я понимаю, что могу выразить все это в одной строке, я не считаю, что это больше » прямой и, следовательно, не ответ на мой вопрос.
Примечание 2: Этот курс, кажется, строит классы общего типа из фундаментальных частей. Мы начали с пользовательской реализации List
, за которой следовал Functor
, а теперь Applicative
, поэтому я могу использовать только концепции из этих классов. Я пока не могу использовать что-либо от Monad
.