Как сгладить список опций

#filtering #optional #reason #bucklescript

#фильтрация #необязательно #Причина #bucklescript

Вопрос:

Теперь у меня есть этот фрагмент кода:

  results
 |> List.filter(Belt.Option.isSome)
 |> List.map(item =>
      switch (item) {
      | Some(item) => item
      }
    )
 

Кто-нибудь может сделать это короче? Это фильтр, который удаляет недопустимые значения, за которыми следует сопоставление, которое преобразует / разворачивает необязательные значения в просто значения.

В Scala это было бы просто flatten :

 scala> List(Some("test"),None,None,Some("foo"),Some("bar"),None).flatten
res4: List[String] = List(test, foo, bar)
 

Комментарии:

1. Как сформулировано, этот вопрос больше подходит для проверки кода . Вы должны задать конкретные вопросы по SO. Я попытаюсь просто ответить, как сгладить list вместо option s.

2. Я взял хирургический нож на ваш вопрос, чтобы добраться до сути. Надеюсь, все в порядке. Я думаю, что это отличный вопрос, сформулированный таким образом.

3. спасибо, да, определенно так лучше

Ответ №1:

flatten в Scala, похоже, работает с любым типом монады. И этот вид полиморфизма, называемый специальным полиморфизмом, к сожалению, не поддерживается в OCaml (хотя он включен в дорожную карту, как функция под названием «модульные импликации»). Поэтому мы должны написать код, специфичный для list s из option s. Используя just Belt , мы можем сделать это:

 [Some("test"), None, None, Some("foo"), Some("bar"), None]
|> Belt.List.keepMap(_, x => x)
 

keepMap это то, что вызывается filterMap в более разумных стандартных библиотеках, и принимает функцию, которая должна возвращать an option вместо a bool , где a None будет отфильтровано и Some(x) будет сглажено и включено в окончательный список как just x .

Комментарии:

1. Просто небольшое замечание, что (хотя Гленн не фанат) библиотека Belt предназначена для хорошей работы с оператором pipe-first, так что это тоже может быть [...]->Belt.List.keepMap(x => x) .

2. Действительно 🙂 Версия оператора первого канала, зависящая от причины, особенно плоха, потому что приоритет оператора отличается, что может привести к неожиданным ошибкам, если вы смешаете его с обычным оператором канала.

3. отлично, спасибо. Добавлен вариант для воспроизведения здесь: reasonml.github.io/en /…