Я пытаюсь понять, что делает оператор точка в этом коде Haskell:
sumEuler = sum . (map euler) . mkList
Полный исходный код ниже.
Мое понимание
Оператор точки принимает две функции, sum
а также результат map euler
и результат в mkList
качестве входных данных.
Но sum
разве функция не является аргументом функции, верно? и так, что здесь происходит?
Кроме того, что (map euler)
делает?
Код
mkList :: Int -> [Int]
mkList n = [1..n-1]
euler :: Int -> Int
euler n = length (filter (relprime n) (mkList n))
sumEuler :: Int -> Int
sumEuler = sum . (map euler) . mkList
источник
f (g x)
=(f . g) x
"?) Или что-то еще?==
Вместо этого вам понадобится действующий стандартный Haskell.Файл. оператор составляет функции. Например,
a . b
Где a и b - функции, это новая функция, которая запускает b для своих аргументов, а затем a для этих результатов. Ваш код
sumEuler = sum . (map euler) . mkList
точно так же, как:
sumEuler myArgument = sum (map euler (mkList myArgument))
но надеюсь легче читать. Причина, по которой вокруг map euler есть скобки, заключается в том, что это делает более ясным, что есть 3 составляемые функции: sum , map euler и mkList - map euler - это одна функция.
источник
sum
- это функция в Haskell Prelude, а не аргументsumEuler
. Имеет типNum a => [a] -> a
Оператор композиции функции
.
имеет типИтак, у нас есть
euler :: Int -> Int map :: (a -> b ) -> [a ] -> [b ] (map euler) :: [Int] -> [Int] mkList :: Int -> [Int] (map euler) . mkList :: Int -> [Int] sum :: Num a => [a ] -> a sum . (map euler) . mkList :: Int -> Int
Обратите внимание, что
Int
это действительно экземпляр классаNum
типов.источник
Файл. Оператор используется для композиции функции. Как и в математике, если вам нужны функции f (x) и g (x) f. g становится f (g (x)).
map - это встроенная функция, которая применяет функцию к списку. Если поместить функцию в скобки, она рассматривается как аргумент. Термин для этого - карри . Вы должны это посмотреть.
Что он делает, так это то, что он принимает функцию с двумя аргументами, он применяет аргумент эйлера. (карта Эйлера) верно? и результатом является новая функция, которая принимает только один аргумент.
сумма. (карта Эйлера). mkList - это, по сути, отличный способ собрать все это вместе. Я должен сказать, что мой Haskell немного устарел, но, может быть, вы сможете сами собрать эту последнюю функцию?
источник
Короткий ответ
Эквивалентный код без точек, это просто
sumEuler = \x -> sum ((map euler) (mkList x))
или без лямбды
sumEuler x = sum ((map euler) (mkList x))
потому что точка (.) указывает на композицию функции.
Более длинный ответ
Во-первых, давайте упростим частичное применение
euler
кmap
:map_euler = map euler sumEuler = sum . map_euler . mkList
Теперь у нас есть только точки. Что обозначено этими точками?
Из источника :
Таким образом ,
(.)
является Сотроз оператором .Сочинять
В математике мы могли бы записать композицию функций f (x) и g (x), то есть f (g (x)), как
что можно читать как «f, составленная с g».
Итак, в Haskell f ∘ g или f, составленный с g, можно записать:
f . g
Композиция ассоциативна, что означает, что f (g (h (x))), записанная с помощью оператора композиции, может опускать скобки без какой-либо двусмысленности.
То есть, поскольку (f ∘ g) ∘ h эквивалентно f ∘ (g ∘ h), мы можем просто написать f ∘ g ∘ h.
Кружу назад
Возвращаясь к нашему предыдущему упрощению, это:
sumEuler = sum . map_euler . mkList
просто означает, что
sumEuler
это непримененная композиция этих функций:sumEuler = \x -> sum (map_euler (mkList x))
источник
Оператор точки применяет функцию слева (
sum
) к выходу функции справа. В вашем случае вы объединяете в цепочку несколько функций - вы передаете результатmkList
в(map euler)
, а затем передаете результат вsum
. На этом сайте есть хорошее введение в некоторые концепции.источник