อะไรคือชื่อของอาร์กิวเมนต์การทำงานในเท่า


10

ในการสั่งซื้อฟังก์ชั่นที่สูงขึ้นพับ / ลดชื่อของการโต้แย้งการทำงานคืออะไรถ้ามี?

ฉันกำลังทำงานกับไลบรารีการประมวลผลแบบตารางเดี่ยวที่แถวถูกพับเพื่อทำการวิเคราะห์อย่างง่าย (เช่นการค้นหาคอลัมน์ขั้นต่ำสูงสุดและค่าเฉลี่ย) ฉันกำลังมองหาชื่อเสียงสำหรับการโต้แย้งของfoldฟังก์ชั่นและชื่อใด ๆ ที่เป็นที่ยอมรับในชุมชน ML (หรือ Haskell หรือ Common LISP ในฐานะผู้สมัครที่สองและสาม) น่าสนใจ

ชื่อชอบfเป็นเรื่องธรรมดาในคำอธิบายของfoldฟังก์ชั่น แต่มันไม่ได้อธิบายและคำนามจะเหมาะกว่า


10
ไม่มีเลย ในความเป็นจริงไม่มีแม้แต่ชื่อที่ใช้อย่างกว้างขวางสำหรับการเปลี่ยนแปลง (พับ)
Daniel Gratzer

2
หากนี่เป็นคำถามสำหรับการมอบหมายงานหรือการสอบคุณต้องได้รับคำตอบจากอาจารย์หรือตำราเรียนไม่ใช่จากเรา เขาอาจจะเรียกมันว่าสิ่งที่แตกต่าง สิ่งที่สอนในห้องเรียนไม่ได้เป็นสิ่งที่ใช้กันทั่วไปในโลกแห่งความเป็นจริง
Robert Harvey

7
@RobertHarvey นี่ไม่ใช่คำถามสอบ (?) หรืออะไรทำนองนั้น ในฐานะโปรแกรมเมอร์ฉันคิดว่าการเลือกชื่อที่ดีสำหรับการเขียนโปรแกรมวัตถุ (ชนิดตัวแปร ฯลฯ ) มีความสำคัญมาก และถ้าบางสิ่งมีชื่อที่รู้จักกันดีก็ไม่มีเหตุผลที่จะไม่ใช้มัน - นอกเหนือจากความไม่รู้และนั่นคือสิ่งที่เป็นคำถาม
user40989

9
@Izkata ไม่ถูกต้อง ฟังก์ชันลำดับที่สูงกว่าคือฟังก์ชันที่รับฟังก์ชั่น foldเป็นฟังก์ชั่นการสั่งซื้อที่สูงขึ้น อาร์กิวเมนต์ที่จะพับเป็นเพียงการโต้แย้ง
Daniel Gratzer

1
@jozefg นั่นเป็นการตอบสนองต่อส่วนที่สองของความคิดเห็นของคุณ ส่วนแรก (และคำถาม) ดูโพสต์ของฉันใน Meta พวกเขาเรียกว่าพารามิเตอร์ขั้นตอน
Izkata

คำตอบ:


8

ฉันไม่รู้ว่ามีคำตอบเดียวสำหรับเรื่องนี้ตามที่ @jozefg พูดถึง และจากการเก็งกำไรอย่างหมดจดนี่เป็นคำอธิบายที่เป็นไปได้:

ฉันสงสัยว่าเป็นเพราะประเภท - (a -> b -> b)ในHaskellfoldrตัวอย่าง - มีความหมายมากกว่าชื่อใด ๆ ที่อาจเกิดขึ้น เนื่องจากพารามิเตอร์aและbประเภทสามารถเป็นอะไรก็ได้ฟังก์ชั่นก็สามารถทำอะไรก็ได้เช่นกัน ดังนั้นคุณจะเหลือที่มีชื่อเหมือนfunction, combiner, morphismและargumentที่ไม่ได้มีความหมายโดยเฉพาะอย่างใดอย่างหนึ่ง อาจใช้ชื่อที่สั้นและไม่รบกวน

อีกตัวอย่างหนึ่งคือid :: a -> aฟังก์ชั่น: สิ่งที่คุณควรเรียกอาร์กิวเมนต์ของมัน? ฉันคิดว่าidประเภทของคำบรรยายมีความหมายมากกว่าชื่ออาร์กิวเมนต์

อย่างไรก็ตามฉันเห็นด้วยกับคุณ - ดูเหมือนว่าควรมีชื่อสามัญบางทีในวิชาคณิตศาสตร์ ฉันหวังว่าบางคนสามารถแก้ไขฉันได้


ตัวอย่างบางส่วนของชื่อในรหัสจริง:

ในห้องสมุดของ Haskellนั้นส่วนใหญ่จะเรียกว่าf(และบางครั้งoperatorในความคิดเห็น):

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

มันเรียกว่าf ใน 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

ผมไม่เห็นด้วยกับความคิดที่ว่าเป็นชื่อที่ต่ำในการโต้แย้งการทำงานของf foldเหตุผลที่เราต้องการชื่ออธิบายในการเขียนโปรแกรมคือเพื่อให้เรารู้ว่าชื่ออธิบายอะไรและชื่อfนี้ใช้กันทั่วไปในวิชาคณิตศาสตร์ (และภาษาโปรแกรมการทำงาน) สำหรับฟังก์ชั่น (ตามที่เป็นgและh)

เราไม่รู้อะไรเกี่ยวกับf(โดยการออกแบบเนื่องจากถ้าเราสามารถเจาะจงได้มากขึ้นเราไม่สามารถใช้foldหลายสิ่งได้) และชื่อfบอกเราทุกสิ่งที่เราจำเป็นต้องรู้ยกเว้นว่ามันเป็นหน้าที่ของสองข้อโต้แย้ง ชื่อfมีความคล้ายคลึงกับสรรพนาม 'it' ในภาษาอังกฤษ - มันเป็นตัวยึดตำแหน่งซึ่งอาจหมายถึงเกือบทุกอย่าง เราไม่ทราบว่าสิ่งที่มันเป็นจนกว่าเราจะใช้มันในประโยคและเราไม่ทราบว่าเป็นจนกว่าเราจะเรียก ffold

เมื่อตั้งชื่อสิ่งต่าง ๆ เราต้องการได้รับข้อมูลมากที่สุดเท่าที่จะเป็นไปได้และเราต้องการให้ชื่อนั้นสั้น (ถ้าเราสามารถทำได้โดยไม่ต้องเสียสละข้อมูลสำคัญ) ที่นี่เรามีมากชื่อสั้น ๆ ที่บอกเราเกือบทุกอย่างที่เรารู้เกี่ยวกับมัน ฉันไม่คิดว่ามันจะดีขึ้น

ในการเขียนโปรแกรมที่จำเป็นiจะใช้เป็นตัวนับลูป (ตามที่เป็นjและkถ้าเราต้องการมากขึ้น); ในฟังก์ชั่นการเขียนโปรแกรมfใช้สำหรับการโต้แย้งฟังก์ชั่นในฟังก์ชั่นการสั่งซื้อที่สูงขึ้น (เช่นเดียวกับgและhถ้าเราต้องการมากขึ้น) ฉันไม่มีประสบการณ์มากพอกับภาษาที่ใช้งานได้เพื่อให้แน่ใจว่าการประชุม f / g / h นั้นได้รับการยอมรับเช่นเดียวกับการประชุม I / j / k แต่ถ้ามันไม่เป็นเช่นนั้นฉันคิดว่ามันควรจะเป็น ก่อตั้งขึ้นในคณิตศาสตร์)


3

ชื่อที่พบมากที่สุดสำหรับเรื่องนี้ที่ผมเคยได้ยินอื่นนอกเหนือจากคำสรรพนามfจะเป็นbinary operationหรือbinary function- ปัญหากับการเป็นที่เฉพาะเจาะจงมากขึ้นกว่าที่มันสามารถทำอักษรอะไรและที่ว่าทำไมคนติดลายเซ็นชนิดa -> b -> a(หรือa -> b -> bถ้ามันพับขวา) .

ดังนั้นผมจึงเสนอว่าคุณทำตรงนั้นติดลายเซ็นชนิดโชคดีว่าลายเซ็นประเภทที่เฉพาะเจาะจงจะมีชื่อ: binary functionเหมือนa -> aเป็นunary operationและa -> bเป็นunary functionคุณสามารถเรียกและa -> a -> abinary operationa -> b -> cbinary function


1
สำหรับฉันbinary operationจะหมายถึงมากขึ้นa -> a -> aและbinary functionจะยืนหยัดa -> b -> c... ความจริงก็คืออยู่ระหว่าง :-)
user40989

@ user40989 การโทรที่ดีถูกแก้ไข
Jimmy Hoffa

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.