Spec-Zone.ru › Haskell 9

Data.Function

Авторские права Нильс Андерс Даниэльссон 2006
Александр Бернтсен 2014
Лицензия BSD-стиль (см. файл LICENSE в дистрибутиве)
Поддержка libraries@haskell.org
Устойчивость стабильная
Переносимость переносимая
Safe Haskell Безопасная
Язык Haskell2010

Содержание

  • Prelude повторный экспорт
  • Другие комбинаторы

Описание

Простые комбинаторы, работающие только с функциями.

Prelude повторный экспорт

id :: a -> a Источник

Функция тождества.

id x = x

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

Примеры
Развернуть
>>> length $ filter id [True, True, False, True]
3
>>> Just (Just 3) >>= id
Just 3
>>> foldr id 0 [(^3), (*5), (+2)]
1000

const :: a -> b -> a Источник

const x y всегда вычисляется в x, игнорируя свой второй аргумент.

const x = \_ -> x

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

Примеры
Развернуть
>>> const 42 "hello"
42
>>> map (const 42) [0..3]
[42,42,42,42]

(.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 Источник

Композиция функций справа налево.

(f . g) x = f (g x)
f . id = f = id . f
Примеры
Развернуть
>>> map ((*2) . length) [[], [0, 1, 2], [0]]
[0,6,2]
>>> foldr (.) id [(+1), (*3), (^3)] 2
25
>>> let (...) = (.).(.) in ((*2)...(+)) 5 10
30

flip :: (a -> b -> c) -> b -> a -> c Источник

flip f меняет местами свои (первые) два аргумента в обратном порядке от f.

flip f x y = f y x
flip . flip = id
Примеры
Развернуть
>>> flip (++) "hello" "world"
"worldhello"
>>> let (.>) = flip (.) in (+1) .> show $ 5
"6"

($) :: (a -> b) -> a -> b infixr 0 Источник

($) - это оператор применения функции.

Применение ($) к функции f и аргументу x даёт тот же результат, что и применение f к x непосредственно. Определение аналогично этому:

($) :: (a -> b) -> a -> b
($) f x = f x

Это id, специализированное из a -> a в (a -> b) -> (a -> b), что по ассоциативности (->) равно (a -> b) -> a -> b.

На первый взгляд это может показаться бессмысленным! Но на самом деле это один из самых полезных и важных операторов в Haskell.

Порядок операций сильно отличается между ($) и обычным применением функции. Обычное применение функции имеет приоритет 10 - выше, чем любой оператор - и ассоциируется слева. Таким образом, эти два определения эквивалентны:

expr = min 5 1 + 5
expr = ((min 5) 1) + 5

($) имеет приоритет 0 (самый низкий) и ассоциируется справа, поэтому они эквивалентны:

expr = min 5 $ 1 + 5
expr = (min 5) (1 + 5)
Примеры
Развернуть

Распространенным случаем использования ($) является избегание скобок в сложных выражениях.

Например, вместо использования вложенных скобок в следующей функции Haskell:

-- | Sum numbers in a string: strSum "100  5 -7" == 98
strSum :: String -> Int
strSum s = sum (mapMaybe readMaybe (words s))

мы можем использовать оператор применения функции:

-- | Sum numbers in a string: strSum "100  5 -7" == 98
strSum :: String -> Int
strSum s = sum $ mapMaybe readMaybe $ words s

($) также используется как секция (частично примененный оператор), чтобы указать, что мы хотим применить какую-то еще не определенную функцию к заданному значению. Например, чтобы применить аргумент 5 к списку функций:

applyFive :: [Int]
applyFive = map ($ 5) [(+1), (2^)]
>>> [6, 32]
Техническое замечание (Полиморфизм представлений)
Развернуть

($) полностью полиморфно по представлению. Это позволяет использовать его также с аргументами неуказанных и даже неупакованных типов, таких как неупакованные целые числа:

fastMod :: Int -> Int -> Int
fastMod (I# x) (I# m) = I# $ remInt# x m

Другие комбинаторы

(&) :: a -> (a -> b) -> b infixl 1 Источник

& - это оператор обратного применения. Это обеспечивает удобство записи. Его приоритет на единицу выше, чем у оператора прямого применения $, что позволяет & быть вложенным в $.

Это версия flip id, где id специализируется из a -> a в (a -> b) -> (a -> b) , что по ассоциативности (->) равно (a -> b) -> a -> b. Перевернув это, получим a -> (a -> b) -> b, что соответствует типу подписи &

Примеры
Развернуть
>>> 5 & (+1) & show
"6"
>>> sqrt $ [1 / n^2 | n <- [1..1000]] & sum & (*6)
3.1406380562059946

С версии: base-4.8.0.0

fix :: (a -> a) -> a Источник

fix f - это наименьшая неподвижная точка функции f, т.е. наименьшее определенное x такое, что f x = x.

Когда f строго, это означает, что из-за определения строгости f ⊥ = ⊥ и так далее наименьшая определенная неподвижная точка любой строгой функции - это ⊥.

Примеры
Развернуть

Мы можем записать функцию факториала с помощью прямой рекурсии как

>>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5
120

Это использует тот факт, что let Haskell’а вводит рекурсивные связки. Мы можем переписать это определение с использованием fix,

Вместо прямого рекурсивного вызова мы вводим псевдо-параметр rec; когда он используется внутри fix, этот параметр относится к аргументу fix , следовательно, рекурсия вводится повторно.

>>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5
120

Используя fix, мы можем реализовать версии repeat как fix . (:) и cycle как fix . (++)

>>> take 10 $ fix (0:)
[0,0,0,0,0,0,0,0,0,0]
>>> map (fix (\rec n -> if n < 2 then n else rec (n - 1) + rec (n - 2))) [1..10]
[1,1,2,3,5,8,13,21,34,55]
Подробности реализации
Развернуть

Текущая реализация fix использует структурное совместное использование

fix f = let x = f x in x

Более простая, но не использующая совместное использование версия будет выглядеть так

fix f = f (fix f)

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c infixl 0 Источник

on b u x y применяет двоичную функцию b к результатам применения унарной функции u к двум аргументам x и y. С противоположной точки зрения, она преобразует два входа и объединяет выходы.

(op `on` f) x y = f x `op` f y
Примеры
Развернуть
>>> sortBy (compare `on` length) [[0, 1, 2], [0, 1], [], [0]]
[[],[0],[0,1],[0,1,2]]
>>> ((+) `on` length) [1, 2, 3] [-1]
4
>>> ((,) `on` (*2)) 2 3
(4,6)
Алгебраические свойства
Развернуть
  • (*) `on` id = (*) -- (if (*) ∉ {⊥, const ⊥})
  • ((*) `on` f) `on` g = (*) `on` (f . g)
  • flip on f . flip on g = flip on (g . f)

applyWhen :: Bool -> (a -> a) -> a -> a Источник

applyWhen применяет функцию к значению, если условие истинно, в противном случае возвращает значение без изменений.

Это эквивалентно flip (bool id).

Примеры
Развернуть
>>> map (\x -> applyWhen (odd x) (*2) x) [1..10]
[2,2,6,4,10,6,14,8,18,10]
>>> map (\x -> applyWhen (length x > 6) ((++ "...") . take 3) x) ["Hi!", "This is amazing", "Hope you're doing well today!", ":D"]
["Hi!","Thi...","Hop...",":D"]
Алгебраические свойства
Развернуть
  • applyWhen True = id
  • applyWhen False f = id

С версии: base-4.18.0.0

© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.12.1/docs/libraries/base-4.21.0.0-8e62/Data-Function.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API