簡體   English   中英

此函數是否有任何用例:foo ::(b-> c)->(a-> b)->(a-> c)

[英]Are there any use cases for this function : foo :: (b -> c) -> (a -> b) -> (a -> c)

對於此功能:

foo :: (b -> c) -> (a -> b) -> (a -> c)

取自http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html

這是沒有實際用途的功能嗎? 除非類型c是此函數中的另一個輸入參數,否則無法構造(b -> c)

(a -> b) -> (a -> c) :b和c不是這些函數的輸入參數。

此功能有用例嗎?

如果問題是關於在實踐中使用函數組合的,那么這里是一個小例子。 假設我們要編寫一個函數,該函數將數字列表的所有元素的平方和。 我們該怎么做? 好吧,我們可以這樣寫: squareSum xs = sum (map (^2)) xs 但是我們也可以改用函數組合: squareSum = sum . map (^2) squareSum = sum . map (^2) (我在函數組合中使用.而不是foo ,但這並不重要)。 此示例顯示了使用函數組合獲得的函數(至少在某種意義上說它可以正確編譯和正常工作是可行的)。 當我們需要組合多個功能(可能部分應用)時,功能組合的好處變得更加明顯。

可以構造函數b -> c由於bc可以是任何類型,因此任何函數都與之兼容。 但是,由於函數foo不了解bc因此它本身不能(明智地)構造此類函數。 這是一個很大的好處,因為它大大減少了函數foo的可能實現數量。 這稱為參數性

此函數是函數組合運算符(.)

我只是想補充一下(.)可能在任何良好的Haskell代碼庫中使用最多的前三個函數中。 它肯定在我的代碼中。

前三名中的另外兩個是由於整數而由編譯器插入的對fromInteger隱式調用,以及對來自do表示法的(>>=)隱式調用。 從深度上講,后者的操作與(.)相同,但類型略有不同的值。

為了補充其他答案,讓我嘗試證明只有一個(全部)功能

foo :: (b -> c) -> (a -> b) -> (a -> c)

或者換句話說, foo = (.) 通過擴展性,我們想證明

foo f g n = f (g n)

其中f,g,nfoo簽名所要求的類型的縮寫值。

f :: b -> c
g :: a -> b
n :: a

我們從相關的自由定理開始,該定理可以在網絡上自動生成

forall t1,t2 in TYPES, R in REL(t1,t2).
 forall t3,t4 in TYPES, S in REL(t3,t4).
  forall t5,t6 in TYPES, R1 in REL(t5,t6).
   forall p :: t3 -> t5.
    forall q :: t4 -> t6.
     (forall (x, y) in S. (p x, q y) in R1)
     ==> (forall r :: t1 -> t3.
           forall s :: t2 -> t4.
            (forall (z, v) in R. (r z, s v) in S)
            ==> (forall (w, u) in R.
                  (foo p r w, foo q s u) in R1))

讓我們通過專門化它來簡化這個龐大的公式。 我們選擇:

t1 = a    t2 = ()
t3 = b    t4 = ()
t5 = c    t6 = ()

我們選擇以下關系:

R = { (n       , ()) }  which is indeed in REL(t1,t2) = REL(a,())
S = { (g n     , ()) }  which is indeed in REL(t3,t4) = REL(b,())
R1= { (f (g n) , ()) }  which is indeed in REL(t5,t6) = REL(c,())

自由定理變為:

   forall p :: b -> c.
    forall q :: () -> ().
     (forall (x, y) in S. (p x, q y) in R1)
     ==> (forall r :: a -> b.
           forall s :: () -> ().
            (forall (z, v) in R. (r z, s v) in S)
            ==> (forall (w, u) in R.
                  (foo p r w, foo q s u) in R1))

根據SR1定義,我們選擇p = fq = id

     (forall x = g n, y = () . f x = f (g n) /\ y = id y)
     ==> (forall r :: a -> b.
           forall s :: () -> ().
            (forall (z, v) in R. (r z, s v) in S)
            ==> (forall (w, u) in R.
                  (foo f r w, foo id s u) in R1))

頂層含義的前提是正確的,因此我們將其消除。 現在,我們選擇r = gs = id 根據r1R定義,我們得到:

            (forall z = n, v = () . g z = g n , id v = ())
            ==> (forall (w, u) in R.
                  (foo f g w, foo id id u) in R1)

我們可以釋放真正的前提。 此外,我們可以選擇w = nu = () 我們最終獲得:

                  foo f g n = f (g n) /\ foo id id u = ()

優質教育

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM