Что такое <|> в haskell?
Я все еще изучаю haskell и смотрю snap веб-фреймворк. В их приветственном примере мира есть вещь, которая выглядит как <|>
site :: Snap ()
site =
ifTop (writeBS "hello world") <|>
route [ ("foo", writeBS "bar")
, ("echo/:echoparam", echoHandler)
] <|>
dir "static" (serveDirectory ".")
Google для этого удивительно сложно, и документация snap просто использует <|>
как существительное. Что это такое и что он делает?
Ответы
Ответ 1
Это метод в классе Alternative
в модуле Control.Applicative
в пакете base
.
Обычно это означает, что вы имеете дело с каким-то вычислением, которое может потерпеть неудачу и продолжить. Если оба x
и y
набраны как m a
, где m
теги такого рода вычислений, о которых мы говорим, тогда
x <|> y :: m a
- это вычисление, которое "пытается" x
, и если оно терпит неудачу, то "пытается" y
. Такие экземпляры вычислений составляют Alternative
.
Ответ 2
Цитирование оснастки <
Если вы не знакомы с Haskell, вам может быть интересно узнать о & Л; | > . Это просто бинарный оператор, который оценивает свой первый аргумент, и если он не прошел, он оценивает второй. Если первый аргумент преуспел, то он останавливается, не оценивая второй аргумент.
Функция сайта использует < | | > для подключения трех различных функций, которые охранять, какая страница отображается. Сначала выполняется функция ifTop. Эта функция выполнена успешно, если запрашиваемый URL-адрес - http://site.com. Если это происходит, затем Snap отправляет ответ "hello world". В противном случае выполняется функция маршрута.
Ответ 3
Я согласен с Xeo в той степени, что < | | > имеет эффект игнорирования пустого списка в [] < | > [1,2,3], но под капотом компилятор может конкатенировать пустой список с непустым списком. У меня есть ghci, чтобы автоматически отображать типы распечаток. Вот некоторые результаты, которые предполагают, что в случае списков < | > и ++ могут быть эквивалентными:
λ: [] <|> [3,4]
[3,4]
it :: Num a => [a]
λ: [] ++ [3,4]
[3,4]
it :: Num a => [a]
λ: [1,2] <|> [3,4]
[1,2,3,4]
it :: Num a => [a]
λ: [1,2] ++ [3,4]
[1,2,3,4]
it :: Num a => [a]
λ: :t (<|>) [1,2] [3,4]
(<|>) [1,2] [3,4] :: Num a => [a]
λ: :t (++) [1,2] [3,4]
(++) [1,2] [3,4] :: Num a => [a]
λ: [1,2] <|> [] <|> [3,4]
[1,2,3,4]
Ну, < | > имеет эффект ++ в приведенных выше примерах, но есть больше, чем это происходит. В https://hackage.haskell.org/package/parsec-3.0.0/docs/Text-ParserCombinators-Parsec-Prim.html мы читаем об этом < | > :
"Этот комбинатор определен равным члену mplus класса MonadPlus и (Control.Applicative. < | > ) член Control.Applicative.Alternative."
Обращаясь к обсуждению Hackage "Control.Monad", мы читаем:
mss:: MonadPlus m = > [m a] → m a Источник ", за которым следует" Это обобщает функцию concat на основе списка".
Ответ на вопрос "Что делает < | > do?" Коренится в понимании того, что делают компиляторы Haskell, когда они сталкиваются < | > , говорят в "[] < | > [1,2,3]"? Они просто игнорируют []? Выполняют ли они процедуру конкатенации? Есть шаги, связанные с выяснением того, что делать с этим странно перегруженным оператором. Неудивительно, что программисты его озадачивают и соглашаются на то, что знают немного больше, чем эффект от использования его в особых случаях использования.
< | > полезен для выпрыгивания из рекурсивных петель, как только выполняется условие. Вот некоторый код, чтобы предложить, как это работает:
λ: Nothing <|> Just 6 <|> Just 7
Just 6
it :: Num a => Maybe a
λ: Nothing <|> Just [1,2] <|> Nothing <|> Just [3,4]
Just [1,2]
it :: Num t => Maybe [t]