Поиск…


замечания

Большинство функций Haskell вызывается с именем функции, за которым следуют аргументы (префиксная нотация). Для функций, которые принимают два аргумента типа (+), иногда имеет смысл предоставить аргумент до и после функции (infix).

прелюдия

логический

&& является логическим И, || является логическим ИЛИ.

== - равенство, /= не равенство, < / <= меньше и > / >= более крупные операторы.

Арифметические операторы

Численные операторы + , - и / ведут себя в основном так, как вы ожидали. (Отдел работает только с дробными номерами, чтобы избежать проблем округления - целочисленное деление должно выполняться с помощью quot или div ). Более необычными являются три оператора возведения в степень Хаскелла:

  • ^ берет базу любого типа номера в неотрицательную интегральную мощность. Это работает просто ( быстрым ) повторным умножением. Например

    4^5  ≡  (4*4)*(4*4)*4
    
  • ^^ делает то же самое в положительном случае, но и работает для отрицательных показателей. Например

    3^^(-2)  ≡  1 / (2*2)
    

    В отличие от ^ , для этого требуется дробный базовый тип (т. 4^^5 :: Int не будет работать, только 4^5 :: Int или 4^^5 :: Rational ).

  • ** реализует возведение в степень реального числа. Это работает для очень общих аргументов, но более усложнительно дорого, чем ^ или ^^ , и, как правило, берет небольшие ошибки с плавающей запятой.

    2**pi  ≡  exp (pi * log 2)
    

Списки

Существует два оператора конкатенации:

  • : (произносится cons ) добавляет один аргумент перед списком. Этот оператор фактически является конструктором и поэтому может также использоваться для сопоставления шаблонов («инверсная конструкция») списка.

  • ++ объединяет целые списки.

    [1,2] ++ [3,4]  ≡  1 : 2 : [3,4]  ≡  1 : [2,3,4]  ≡  [1,2,3,4]
    

!! является индексирующим оператором.

[0, 10, 20, 30, 40] !! 3  ≡  30

Обратите внимание, что списки индексирования неэффективны (сложность O ( n ) вместо O (1) для массивов или O (log n ) для карт ); обычно Haskell предпочитает деконструировать списки, сворачивая сопоставление шаблонов ot вместо индексации.

Управляющий поток

  • $ - оператор приложения функции.

    f $ x  ≡  f x
           ≡  f(x)  -- disapproved style
    

    Этот оператор в основном используется для исключения скобок. Он также имеет строгую версию $! , который заставляет аргумент оцениваться перед применением функции.

  • . Составляет функции.

    (f . g) x  ≡  f (g x)  ≡  f $ g x
    
  • >> последовательности монадических действий. Например, writeFile "foo.txt" "bla" >> putStrLn "Done." сначала напишите в файл, затем распечатайте сообщение на экране.

  • >>= делает то же самое, а также принимает аргумент, который должен быть передан от первого действия к следующему. readLn >>= \x -> print (x^2) будет ждать ввода пользователем числа, а затем вывести квадрат этого числа на экран.

Пользовательские операторы

В Haskell вы можете определить любой инфиксный оператор, который вам нравится. Например, я мог бы определить оператор обертывания списка как

(>+<) :: [a] -> [a] -> [a]
env >+< l = env ++ l ++ env

GHCi> "**">+<"emphasis"
"**emphasis**"

Вы должны всегда давать этим операторам объявление о фиксации , например

infixr 5 >+<

(что означает, что >+< связывается так же сильно, как ++ и : do).

Поиск информации об инфиксных операторах

Поскольку в Haskell настолько распространены инфиксы, вам регулярно нужно искать их подпись и т. Д. К счастью, это так же просто, как и для любой другой функции:

  • Поисковые системы Haskell Hayoo и Hoogle могут использоваться для инфиксных операторов, как и для любого другого, определенного в некоторой библиотеке.

  • В GHCi или IHaskell вы можете использовать директивы :i и :t ( i nfo и t ype), чтобы узнать основные свойства оператора. Например,

    Prelude> :i +
    class Num a where
      (+) :: a -> a -> a
      ...
          -- Defined in ‘GHC.Num’
    infixl 6 +
    Prelude> :i ^^
    (^^) :: (Fractional a, Integral b) => a -> b -> a
          -- Defined in ‘GHC.Real’
    infixr 8 ^^
    

    Это говорит мне, что ^^ связывается более плотно, чем + , оба берут числовые типы в качестве своих элементов, но ^^ требует, чтобы показатель был интегральным, а база была дробной.
    Менее многословный :t требует оператора в круглых скобках, например

    Prelude> :t (==)
    (==) :: Eq a => a -> a -> Bool
    


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow