#Higer-Order Functionsとは
readingより。簡潔に「関数を引数として取り値をアウトプットする関数」のこと。
One of the things we should demand from a powerful programming language is the ability to build abstractions by assigning names to common patterns and then to work in terms of the names directly. Functions provide this ability.
##Generalizing numbers
例えば以下の様なスクリプトがあったとする。
from math import sqrt, pi
def area_square(r):
assert r > 0, "A length must be positive."
return r * r
def area_circle(r):
return r * r * pi
def area_hexagon(r):
return r * r * 3 * sqrt(3) / 2
共通している部分をarea
関数として最初に作ってしまい、掛け合わせる際の微妙な違いはshape_constant
として定義してしまえば後々同じ処理をする際に関数だけを呼べば良い。
from math import sqrt, pi
def area(r, shape_constant):
assert r > 0, "A length must be positive."
return r * r * shape_constant
def area_square(r):
return area(r, 1)
def area_circle(r):
return area(r, pi)
def area_hexagon(r):
return area(r, 3 * sqrt(3) / 2)
##Generalizing over computational processes
def sum_naturals(n):
"""Sum the first N natural numbers
>>> sum_naturals(5)
15
"""
total, k = 0, 1
while k <= n:
total, k = total + k, k + 1
return total
def sum_cubes(n):
"""Sum the first N cubes of natural numbers.
>>> sum_cubes(5)
225
"""
total, k = total + pow(k, 3), k + 1
return total
というスクリプトがあったとする。気づいたかもしれないが上の2つの関数はk
とpow(k, 3)
を除いてほぼ似たような処理を行っている。
これらの関数を一般化すると以下のようになる。
def <name>(n):
total, k = 0, 1
while k <= n:
total, k = total + <term>(k), k + 1
return total
具体的な手順はこちらを参考に
def identitiy(k):
return k
def cube(k):
return pow(k, 3)
def summation(n, term):
"""Sum the first N terms of a sequence.
>>> summation(5, cube)
225
"""
total, k = 0, 1:
while k <= n:
total, k = total + term(k), k + 1
return total
def sum_naturals(n):
"""Sum the first N natural numbers.
>>> sum_naturals(5):
15
"""
total, k = 0, 1
while k <= n:
total, k = total + k, k + 1
return total
def sum_cubes(n):
"""Sum the first N cubes of natural numbers.
>>> sum_cubes(5)
225
"""
total, k = 0, 1
while k <= n:
total, k = total + pow(k, 3), k + 1
return total
ざっくり言うと関数の中の処理一つ一つを分解して互いに共通している部分と異なる部分を分ける。共通している部分は一つの関数としてまとめ、異なる部分は別途関数を用意する。具体的なイメージとしては、
- 複数の関数同士の中で共通している部分(同じ処理)を探し出し、その処理だけをしてくれる関数を作る。ここでいう
summation
関数がそれにあたる。 - 異なる部分(ここでいう
total + k
とtotal + power(k, 3)
)についても別途関数として作っておけば後でその関数を引数として使ってsummation
関数内でまとめて処理が出来てしまうわけだ。
言葉で説明してもわかりづらいので具体例:
def identitiy(k):
return k
def cube(w):
return pow(w, 3)
def summation(n, term):
"""Sum the first N terms of a sequence.
>>> summation(5, cube)
225
"""
total, k = 0, 1
while k <= n:
total, k = total + term(k), k + 1
print(total)
def sum_naturals(n):
"""Sum the first N natural numbers.
>>> sum_naturals(5):
15
"""
return summation(n, cube)
def sum_cubes(n):
"""Sum the first N cubes of natural numbers.
>>> sum_cubes(5)
225
"""
return summation(n, cube)
sum_cubes(5)
#追記:
このリンクいい感じの解説を見つけた。
def outside():
x = 5
def printHam():
print(x)
return (printHam)
myFunc = outside()
myFunc()
#sortedを使ってhigher order function
sorted([5,-2,-1], key=abs) #[-1,-2,5]
が一番分かりやすい例かもしれない。built-in functionであるabs
を使ってsorted()リストの中身の数字を絶対値として扱い、sorted()
で低い順に変え、元の記号を付けて返すという関数。これは厳密にはkey
関数という名でbuilt-in
関数であるabs
を引数として扱っているのでこれもHiger Order Functionの一部といえる。
its a function your gonna call to sort it along with the list of the stuff to be sorted And sorted() is in charge of looping through the list and calling your function to get the values to sort by.