Apa nama argumen fungsional dalam lipatan

10

Dalam tatanan fungsi yang lebih tinggi lipat / perkecil apa namanya, jika ada, argumen fungsional?

Saya sedang mengerjakan perpustakaan pemrosesan tabel monadik tempat baris dilipat untuk menghasilkan analisis sederhana (seperti menemukan minimum, maksimum, rata-rata kolom). Oleh karena itu saya mencari nama yang tepat untuk argumen foldfungsi dan nama apa pun yang sudah mapan di komunitas ML (atau Haskell atau Common Lisp sebagai kandidat kedua dan ketiga) akan menarik.

Nama seperti fumum dalam deskripsi foldfungsi, namun tidak deskriptif dan kata benda akan lebih cocok.

pengguna40989
sumber
10
Tidak ada. Bahkan, bahkan tidak ada nama yang digunakan secara universal untuk katamorfisme (lipatan)
Daniel Gratzer
2
Jika ini adalah pertanyaan untuk tugas sekolah atau ujian, Anda perlu mendapatkan jawaban dari guru atau buku teks, bukan dari kami. Dia mungkin menyebutnya sesuatu yang berbeda. Apa yang diajarkan di kelas tidak selalu apa yang biasa digunakan di dunia nyata.
Robert Harvey
7
@ RobertTarvey Ini bukan pertanyaan ujian (?) Atau yang serupa. Sebagai seorang programmer, saya pikir memilih nama yang bagus untuk objek pemrograman (tipe, variabel dll.) Sangat penting. Dan jika sesuatu memiliki nama yang terkenal, maka tidak ada alasan untuk tidak menggunakannya — selain dari ketidaktahuan, dan itulah gunanya pertanyaan.
user40989
9
@Izkata Tidak, itu tidak benar. Fungsi orde yang lebih tinggi adalah fungsi yang mengambil fungsi. foldadalah fungsi urutan yang lebih tinggi. Argumen untuk dilipat adalah hanya itu, sebuah argumen
Daniel Gratzer
1
@jozefg Itu sebagai jawaban untuk bagian kedua dari komentar Anda. Adapun bagian pertama (dan pertanyaannya), lihat posting saya di Meta. Mereka disebut parameter prosedural.
Izkata

Jawaban:

8

Saya tidak tahu apakah ada satu jawaban untuk ini, seperti yang disebutkan @jozefg. Dan murni dari spekulasi, inilah satu penjelasan yang mungkin:

Saya menduga alasannya adalah karena jenis - (a -> b -> b)dalam Haskellfoldr , misalnya - lebih bermakna daripada nama apa pun yang muncul. Karena parameter adan bketik bisa apa saja , fungsinya bisa melakukan apa saja juga. Jadi kau pergi dengan nama-nama seperti function, combiner, morphism, dan argument, yang tidak sangat berarti baik. Mungkin juga menggunakan nama pendek, tidak mengganggu.

Contoh lain adalah id :: a -> afungsinya: apa yang harus Anda sebut argumennya? Sekali lagi, saya pikir idtipe ini lebih deskriptif daripada nama argumennya.

Namun, saya setuju dengan Anda - sepertinya harus ada nama umum, mungkin dalam matematika. Saya harap seseorang dapat memperbaiki saya dalam hal ini.


Beberapa contoh namanya dalam kode nyata:

Di perpustakaan Haskell , sebagian besar disebut f(dan kadang-kadang operatordi komentar):

class Foldable t where
    -- | Map each element of the structure to a monoid,
    -- and combine the results.
    foldMap :: Monoid m => (a -> m) -> t a -> m
    foldMap f = foldr (mappend . f) mempty

    -- | Right-associative fold of a structure.
    --
    -- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
    foldr :: (a -> b -> b) -> b -> t a -> b
    foldr f z t = appEndo (foldMap (Endo . f) t) z

    -- | Right-associative fold of a structure, 
    -- but with strict application of the operator.
    foldr' :: (a -> b -> b) -> b -> t a -> b
    foldr' f z0 xs = foldl f' id xs z0
      where f' k x z = k $! f x z

    -- | Left-associative fold of a structure.
    --
    -- @'foldl' f z = 'Prelude.foldl' f z . 'toList'@
    foldl :: (a -> b -> a) -> a -> t b -> a
    foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z

    -- | Left-associative fold of a structure.
    -- but with strict application of the operator.
    --
    -- @'foldl' f z = 'List.foldl'' f z . 'toList'@
    foldl' :: (a -> b -> a) -> a -> t b -> a
    foldl' f z0 xs = foldr f' id xs z0
      where f' x k z = k $! f z x

    -- | A variant of 'foldr' that has no base case,
    -- and thus may only be applied to non-empty structures.
    --
    -- @'foldr1' f = 'Prelude.foldr1' f . 'toList'@
    foldr1 :: (a -> a -> a) -> t a -> a
    foldr1 f xs = fromMaybe (error "foldr1: empty structure")
                    (foldr mf Nothing xs)
      where
        mf x Nothing = Just x
        mf x (Just y) = Just (f x y)

    -- | A variant of 'foldl' that has no base case,
    -- and thus may only be applied to non-empty structures.
    --
    -- @'foldl1' f = 'Prelude.foldl1' f . 'toList'@
    foldl1 :: (a -> a -> a) -> t a -> a
    foldl1 f xs = fromMaybe (error "foldl1: empty structure")
                    (foldl mf Nothing xs)
      where
        mf Nothing y = Just y
        mf (Just x) y = Just (f x y)

-- instances for Prelude types

instance Foldable Maybe where
    foldr _ z Nothing = z
    foldr f z (Just x) = f x z

    foldl _ z Nothing = z
    foldl f z (Just x) = f z x

instance Ix i => Foldable (Array i) where
    foldr f z = Prelude.foldr f z . elems
    foldl f z = Prelude.foldl f z . elems
    foldr1 f = Prelude.foldr1 f . elems
    foldl1 f = Prelude.foldl1 f . elems

-- | Monadic fold over the elements of a structure,
-- associating to the right, i.e. from right to left.
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
foldrM f z0 xs = foldl f' return xs z0
  where f' k x z = f x z >>= k

-- | Monadic fold over the elements of a structure,
-- associating to the left, i.e. from left to right.
foldlM :: (Foldable t, Monad m) => (a -> b -> m a) -> a -> t b -> m a
foldlM f z0 xs = foldr f' return xs z0
  where f' x k z = f z x >>= k

-- | Map each element of a structure to an action, evaluate
-- these actions from left to right, and ignore the results.
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
traverse_ f = foldr ((*>) . f) (pure ())

-- | Map each element of a structure to a monadic action, evaluate
-- these actions from left to right, and ignore the results.
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
mapM_ f = foldr ((>>) . f) (return ())

Itu juga disebut f dalam Clojure :

(def
    ^{:arglists '([f coll] [f val coll])
      :doc "f should be a function of 2 arguments. If val is not supplied,
  returns the result of applying f to the first 2 items in coll, then
  applying f to that result and the 3rd item, etc. If coll contains no
  items, f must accept no arguments as well, and reduce returns the
  result of calling f with no arguments.  If coll has only 1 item, it
  is returned and f is not called.  If val is supplied, returns the
  result of applying f to val and the first item in coll, then
  applying f to that result and the 2nd item, etc. If coll contains no
  items, returns val and f is not called."
      :added "1.0"}    
    reduce
     (fn r
       ([f coll]
             (let [s (seq coll)]
               (if s
                 (r f (first s) (next s))
                 (f))))
       ([f val coll]
          (let [s (seq coll)]
            (if s
              (if (chunked-seq? s)
                (recur f 
                       (.reduce (chunk-first s) f val)
                       (chunk-next s))
                (recur f (f val (first s)) (next s)))
              val)))))

sumber
6

Saya tidak setuju dengan gagasan yang fmerupakan nama buruk untuk argumen fungsi fold. Alasan kami menginginkan nama deskriptif dalam pemrograman adalah agar kami tahu apa yang digambarkan oleh namanya, dan nama ftersebut biasa digunakan dalam matematika (dan bahasa pemrograman fungsional) untuk suatu fungsi (sebagaimana adanya gdan h).

Kita hampir tidak tahu apa-apa tentang f(dengan desain, karena jika kita bisa lebih spesifik tentang itu, kita tidak bisa menggunakan foldbanyak hal), dan namanya fmemberi tahu kita segala yang perlu kita ketahui, kecuali bahwa itu adalah fungsi dari dua argumen. Nama fini sangat mirip dengan kata ganti 'it' dalam bahasa Inggris - itu adalah penampung yang bisa berarti hampir apa saja. Kita tidak tahu apa itu 'sampai kita menggunakannya dalam kalimat, dan kita tidak tahu apa fitu sampai kita memanggilnya fold.

Saat memberi nama, kami ingin mendapatkan informasi sebanyak mungkin dari nama itu, dan kami lebih suka nama itu singkat (jika kami bisa mendapatkan itu tanpa mengorbankan informasi penting). Di sini, kami memiliki nama yang sangat pendek yang memberi tahu kami hampir semua yang kami ketahui tentangnya. Saya tidak berpikir itu bisa diperbaiki.

Dalam pemrograman imperatif, idigunakan sebagai penghitung lingkaran (sebagaimana adanya jdan k, jika kita membutuhkan lebih banyak); dalam pemrograman fungsional, fdigunakan untuk argumen fungsi dalam fungsi tingkat tinggi (seperti gdan h, jika kita membutuhkan lebih banyak). Saya tidak memiliki pengalaman yang cukup dengan bahasa fungsional untuk memastikan bahwa konvensi f / g / h ditetapkan dengan baik sebagai konvensi i / j / k, tetapi jika tidak, saya pikir itu harus (itu pasti adalah didirikan dalam matematika).

Michael Shaw
sumber
3

Nama yang paling umum untuk ini yang pernah saya dengar selain kata ganti fadalah binary operationatau binary function- masalah dengan lebih spesifik dari itu adalah bisa melakukan apa saja secara harfiah , dan itulah sebabnya orang tetap menggunakan jenis tanda tangan a -> b -> a(atau a -> b -> bjika dilipat dengan benar) .

Jadi saya mengusulkan agar Anda melakukan hal itu, patuhi tanda tangan jenis, untungnya tanda tangan jenis tertentu memiliki nama binary function:, seperti a -> aa unary operation, dan a -> ba unary function, Anda dapat memanggil a -> a -> aa binary operationdan a -> b -> ca binary function.

Jimmy Hoffa
sumber
1
Bagi saya binary operationakan lebih berarti a -> a -> adan binary functionakan berarti a -> b -> c... kebenaran pasti ada di antara keduanya. :-)
user40989
@ user40989 panggilan bagus, diperbaiki.
Jimmy Hoffa
1

Fungsi yang Anda minta kadang-kadang disebut sebagai "fungsi menggabungkan" (lihat misalnya halaman HaskellWiki di Lipat ), tetapi ini tidak cukup umum untuk menyebutnya terminologi standar.

Dominique Devriese
sumber