Fonksiyonel programlamada “kısmi fonksiyon” ile tam olarak ne kastedilmektedir?


55

Anladığım kadarıyla, kısmi işlevler, bir işleve beklenenden daha az parametre ileterek elde ettiğimiz işlevlerdir. Örneğin, bu doğrudan Python'da geçerliyse:

>>> def add(x,y):
...    return x+y
... 
>>> new_function = add(1)
>>> new_function(2)
3

Yukarıdaki pasajda new_functionkısmi bir işlev vardır. Ancak, Haskell Wiki'ye göre , kısmi fonksiyonun tanımı

Kısmi işlev, belirtilen türdeki tüm olası bağımsız değişkenler için tanımlanmamış bir işlevdir.

benim sorum şu: "kısmi işlev" ile tam olarak ne kastediliyor?


37
Bir kafa karıştırıcı kısmi bir şekilde tatbik bir işlevi ile kısmi fonksiyonu.
Willem Van Onsem

11
Python'ın partialgerçekleştirir kısmi uygulama Haskell otomatik olarak yapar oysa. Wiki girişi , matematikten gelen bir terim olan kısmi işlevlere karşılık gelir .
L3viathan

9
Kesin olarak Haskell kısmi fonksiyon uygulaması yapmaz. Her işlev bir bağımsız değişken alır ve işlev uygulaması bir işlevi tek bir bağımsız değişkene uygular. Currying ilk etapta çoklu argüman işlevlerini simüle ederek başka bir dilde kısmi uygulama olarak düşündüğünüzü simüle eder . Gibi add 3 5bir şey tek bir işlev uygulaması değildir. Bu, önce add5'e uygulanan yeni bir işlev elde etmek için 3'e uygulanır.
chepner

Ve C # 'da bir partialyöntem, proje kod tabanında başka bir yerde isteğe bağlı olarak uygulanan özel bir yöntemin ileri bir bildirimidir .
Dai

1
new_function = functools.partial(add, 1)
Örneğiniz

Yanıtlar:


76

Burada iki kavramı karıştırıyorsunuz. Bir kısmen uygulanan fonksiyon [haskell-wiki] bir ile kısmi işlevli [haskell-wiki] .

Kısmen uygulanan bir işlev:

Haskell'deki kısmi uygulama , birden çok bağımsız değişken alan bir işleve tam sayıdan daha az bağımsız değişken aktarmayı içerir .

oysa kısmi bir fonksiyon aslında tam olmayan bir fonksiyondur:

Kısmi işlev, belirtilen türdeki tüm olası bağımsız değişkenler için tanımlanmamış bir işlevdir.


24
Bu iyi bir cevaptır, ancak cevabın kendisine kısmi bir fonksiyon örneği eklenerek geliştirilebilir.
ApproachingDarknessFish

2
Kısmen uygulanan bir işlevin tam tanımına katıldığımdan emin değilim. Haskell'deki fonksiyonlar her zaman sadece bir argüman alır, asla "çoklu argüman" almaz. "Haskell'de kısmi uygulama (kısmen uygulama)) tanımını, başka bir argümana daha fazla uygulanamayacak bir değer elde etmek için gereken argüman sayısından daha az tedarik etmeyi içerir." ( buradan uyarlanmıştır )
TerryA

21

Kısmi bir işlev (hem fonksiyonel programlama ve matematik bağlamında) tam olarak wiki'nin söylediği şeydir: olası tüm argümanları için tanımlanmamış bir işlev. Programlama bağlamında, "tanımlanmayan" ifadesini genellikle tanımlanmamış davranış, istisnalar veya sonlandırılmama gibi birkaç şeyden biri olarak yorumlarız.

Kısmi işlevin bir örneği, bölen 0 ise tanımlanmayan tamsayı bölümüdür (Haskell'de bir hata atar).

yukarıdaki snippet'te new_function kısmi işlevdir.

Bu kod sadece Python'da bir hataya neden olur, ancak istediğiniz gibi çalışırsa, toplam (kısmi değil) bir işlev olacaktır.

Komutanların daha önce işaret ettiği gibi, büyük olasılıkla bunun kısmen uygulanan bir işlev olacağını düşünüyorsunuz .


18

Cevaplar her şeyi açıklıyor, her dilde sadece bir örnek ekleyeceğim:

def add(x,y):
    return x+y

f = add(1)
print(f(3))

    f = add(1)
TypeError: add() missing 1 required positional argument: 'y'

bu ne kısmi bir işlev ne de curried bir işlevdir , bu yalnızca tüm argümanlarını vermediğiniz bir işlevdir .

Python'da kıvrımlı bir fonksiyon şöyle olmalıdır:

partialAdd= lambda x: lambda y: x + y

plusOne = partialAdd(1)
print(plusOne(3))

4

ve haskell'de:

plus :: Int -> Int -> Int
plus x y = x + y

plusOne = plus 1

plusOne 4

5

Python'da kısmi bir işlev:

def first(ls):
    return ls[0]

print(first([2,4,5]))
print(first([]))

çıktı

2

print(first([]))
  File "main.py", line 2, in first
    return ls[0]
IndexError: list index out of range

Ve Haskell'de bağlantınız ortaya çıktığında:

head [1,2,3]
3

head []
*** Exception: Prelude.head: empty list

Peki toplam fonksiyon nedir?

Temel olarak, tam tersi: bu, bu türdeki herhangi bir giriş için çalışacak bir işlevdir. İşte python'da bir örnek:

def addElem(xs, x):
  xs.append(x)
  return xs

ve bu, küçük bir numara kullanırsanız sonsuz listeler için bile geçerlidir:

def infiniList():
    count = 0
    ls = []
    while True:
        yield ls
        count += 1
        ls.append(count)

ls = infiniList()
for i in range(5):
  rs = next(ls)

print(rs, addElem(rs,6))

[1, 2, 3, 4]
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]

Ve Haskell'deki eşdeğeri:

addElem :: a -> [a] -> [a]
addElem x xs = x : xs

addElem 3 (take 10 [1..])
=> [3,1,2,3,4,5,6,7,8,9,10]

Burada işlevler sonsuza kadar askıda kalmaz. Kavram aynıdır: her liste için işlev çalışır.


Python'un standart kütüphanedeki kısmi işlevleri desteklediğini belirtmek gerekir .
Monica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.