Tên của đối số chức năng trong nếp gấp là gì


10

Trong hàm bậc cao gấp / giảm tên, nếu có, của đối số chức năng là gì?

Tôi đang làm việc trên một thư viện xử lý bảng đơn âm, nơi các hàng được gấp lại để tạo ra các phân tích đơn giản (như tìm mức tối thiểu, tối đa, trung bình của một cột). Do đó, tôi đang tìm kiếm một tên âm thanh cho đối số của foldhàm và bất kỳ tên nào được thiết lập tốt trong cộng đồng ML (hoặc Haskell hoặc Common Lisp là ứng cử viên thứ hai và thứ ba) sẽ rất thú vị.

Một tên như flà phổ biến trong mô tả các foldchức năng, tuy nhiên nó không được mô tả và một danh từ sẽ phù hợp hơn.


10
Không có cái nào cả. Trên thực tế, thậm chí còn không có một tên được sử dụng phổ biến cho dị hình (gấp)
Daniel Gratzer

2
Nếu đây là một câu hỏi cho một bài tập hoặc bài kiểm tra của trường, bạn cần nhận được câu trả lời từ giáo viên hoặc sách giáo khoa, không phải từ chúng tôi. Anh ta có thể gọi nó là một cái gì đó khác nhau. Những gì được dạy trong một lớp học không phải lúc nào cũng là những gì thường được sử dụng trong thế giới thực.
Robert Harvey

7
@RobertHarvey Đây không phải là một câu hỏi thi (?) Hoặc bất cứ điều gì giống nhau. Là một lập trình viên, tôi nghĩ rằng việc chọn tên tốt cho các đối tượng lập trình (loại, biến, v.v.) là rất quan trọng. Và nếu đôi khi có một cái tên nổi tiếng, thì không có lý do gì để không sử dụng nó ngoài sự thiếu hiểu biết, và đó là những câu hỏi dành cho.
dùng40989

9
@Izkata Không, điều đó không chính xác. Hàm bậc cao hơn là hàm có hàm. foldlà một hàm bậc cao hơn. Đối số cần gấp lại chỉ là một đối số
Daniel Gratzer

1
@jozefg Đó là phản hồi cho phần thứ hai của bình luận của bạn. Đối với phần đầu tiên (và câu hỏi), hãy xem bài đăng của tôi trên Meta. Chúng được gọi là tham số thủ tục.
Izkata

Câu trả lời:


8

Tôi không biết nếu có một câu trả lời duy nhất cho vấn đề này, như @jozefg đã đề cập. Và hoàn toàn không phải là sự suy đoán, đây là một lời giải thích khả dĩ:

Tôi nghi ngờ lý do là vì loại - ví dụ như (a -> b -> b)trong Haskellfoldr - có ý nghĩa hơn bất kỳ cái tên nào người ta có thể nghĩ ra. Vì các tham số abkiểu có thể là bất cứ thứ gì , nên hàm cũng có thể làm được khá nhiều thứ. Vì vậy, bạn đang trái với những cái tên như function, combiner, morphism, và argument, mà không phải là đặc biệt có ý nghĩa trong hai. Cũng có thể sử dụng một tên ngắn, không gây xao lãng.

Một ví dụ khác là id :: a -> ahàm: bạn nên gọi đối số của nó là gì? Một lần nữa, tôi nghĩ idkiểu của nó mô tả nhiều hơn tên đối số của nó.

Tuy nhiên, tôi đồng ý với bạn - có vẻ như nên có một tên chung, có lẽ trong toán học. Tôi hy vọng ai đó có thể sửa chữa tôi về điều này.


Một số ví dụ về tên của nó trong mã thực:

Trong các thư viện của Haskell , nó chủ yếu được gọi f(và đôi khi operatortrong các bình luận):

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 ())

Nó cũng được gọi f trong 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)))))

6

Tôi không đồng ý với ý kiến ​​đó flà một tên xấu cho đối số chức năng của fold. Lý do chúng tôi muốn các tên mô tả trong lập trình là để chúng tôi biết tên đó mô tả và tên fthường được sử dụng trong toán học (và các ngôn ngữ lập trình chức năng) cho một hàm (như gh).

Chúng ta hầu như không biết gì về f(theo thiết kế, vì nếu chúng ta có thể cụ thể hơn về nó, chúng ta không thể sử dụng foldnhiều thứ như vậy) và cái tên fcho chúng ta mọi thứ chúng ta cần biết, ngoại trừ đó là chức năng của hai đối số. Tên fnày rất giống với đại từ 'nó' trong tiếng Anh - đó là một giữ chỗ có nghĩa là hầu hết mọi thứ. Chúng tôi không biết "nó" là gì cho đến khi chúng tôi sử dụng nó trong một câu và chúng tôi không biết đó flà gì cho đến khi chúng tôi gọi fold.

Khi đặt tên, chúng tôi muốn lấy càng nhiều thông tin ra khỏi tên càng tốt và chúng tôi thích tên này ngắn hơn (nếu chúng tôi có thể lấy thông tin đó mà không phải hy sinh thông tin quan trọng). Ở đây, chúng tôi có một cái tên rất ngắn cho chúng tôi biết gần như mọi thứ chúng tôi biết về nó. Tôi không nghĩ rằng nó có thể được cải thiện.

Trong lập trình mệnh lệnh, iđược sử dụng như một bộ đếm vòng lặp (như là jk, nếu chúng ta cần nhiều hơn); trong lập trình hàm, fđược sử dụng cho một đối số hàm trong các hàm bậc cao hơn (như là g, và hnếu chúng ta cần nhiều hơn). Tôi không có đủ kinh nghiệm với các ngôn ngữ chức năng để chắc chắn rằng quy ước f / g / h cũng được thiết lập như quy ước i / j / k, nhưng nếu không, tôi nghĩ nó phải như vậy (chắc chắn là vậy thành lập trong toán học).


3

Tên phổ biến nhất cho cái này mà tôi đã nghe khác với đại từ fsẽ là binary operationhoặc binary function- vấn đề với việc cụ thể hơn nó có thể làm bất cứ điều gì theo nghĩa đen , và đó là lý do tại sao mọi người dính vào chữ ký loại a -> b -> a(hoặc a -> b -> bnếu nó gấp đúng) .

Vì vậy, tôi đề nghị bạn làm chính xác điều đó, bám vào chữ ký loại, may mắn là chữ ký loại cụ thể đó có tên : binary function, giống như a -> alà a unary operation, và a -> blà a unary function, bạn có thể gọi a -> a -> aa binary operationa -> b -> ca binary function.


1
Đối với tôi binary operationcó ý nghĩa hơn a -> a -> abinary functionsẽ đại diện cho a -> b -> csự thật, sự thật chắc chắn nằm ở giữa. :-)
dùng40989

@ user40989 gọi tốt, sửa.
Jimmy Hoffa

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.