簡體   English   中英

haskell中的箭頭和函數有何不同?

[英]How are Arrows and Functions different in haskell?

我學習並搜索了一段時間的Arrows,我對Arrow課程的必要性感到有些困惑。 據我所知,Arrow類是函數的抽象,而Arrow A abc表示需要輸入類型b和輸出類型c的東西。 此外,它提供了幾個基本操作,如>>>arrfirst

但是,我找不到類型b -> c標准函數和類型A abc箭頭之間的任何區別。 在我看來, first>>>可以用\\(b, c) -> (fb, c)(.)代替。 此外,由於箭頭內的每個計算都由函數表示,如果我們用這些函數替換箭頭,我認為沒有區別。

簡而言之,我認為Arrows的計算圖的每個節點(類似於https://www.haskell.org/arrows/syntax.html )都可以被Haskell的標准函數替代。 如果是真的,為什么我們使用Arrow而不是函數?

擁有符合某些法則的抽象允許您進行泛型編程。 你可以編程沒有任何類型類(沒有monad,applicatives,沒有相等/排序等),但這將是非常不方便的,因為你將無法編寫利用這些屬性的通用代碼。

就像你說你不想要Ord實例一樣,然后你必須為你可以訂購的每種數據類型單獨重寫Set的實現。

Arrow的觀點是描述那些計算

  • 接受輸入,
  • 產生輸出,和
  • 在中間肯定( 效果是口語表達)。

所以箭頭A bc不是函數a -> b 很可能箭頭在內部實現為一個函數,但是更復雜的一個,實現Arrow接口的目的是描述(除其他外)它們如何構成。

特別是對於箭頭,您有箭頭符號 ,允許您對任何有效的Arrow使用相同的表示法。 舉一個例子,在netwire包中, Wire數據類型實現了Arrow ,因此您可以使用箭頭符號以及所有適用於箭頭的實用程序函數。 如果沒有實例,您必須具有一些特定於網絡的語法,或者只使用netwire提供的功能。

舉個例子:對應於State monad的箭頭是a -> s -> (b, s) 但是兩個這樣的函數不使用(.) 你需要描述它們的構成,而這正是Arrow所做的。


更新:可以有各種可組合性概念,但我想你的意思是功能組合。 是的,這個可組合性來自ArrowCategory超類,它定義了身份和組合。

Arrow的另一部分來自Strong profunctor,因為我最近從了什么是兼容者和箭頭之間的關系? (雖然這不是在類型層次結構中捕獲的,因為Profunctor類型Profunctor Arrow更年輕)。 Profunctors允許由純計算從“雙方”改性,見lmap / rmap / dimapProfunctor 對於箭頭我們有(<<^)(^>>)其被使用表達arr>>>與純箭頭使用構成通過合成BV的箭頭從任一側arr

最后箭頭有強度 wrt (,) ,它由first :: Arrow a => abc -> a (b, d) (c, d)捕獲。 這意味着我們只能在輸入的一部分上使用箭頭,而不會更改另一個。 這允許用“平行線”構造“電路” - first不可能保存計算的一部分的輸出並且稍后在某處使用它。

一個很好的練習是繪制一個表示計算的電路,然后嘗試使用Arrow原語/實用程序表達它,或者使用箭頭語法表示法。 你會看到first (或*** )對此至關重要。

請參閱Arrows可以多任務獲取操作的精美圖紙。

對於更多理論背景箭頭是強Monads可能很有趣(我還沒有讀過)。

那是因為你只看到了Arrow(->)實例。 其他類型也可以聲明Arrow實例,其中操作更復雜。 例如:

instance Monad m => Arrow (Kleisli m) where
    arr f = Kleisli (return . f)
    first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
    second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))

暫無
暫無

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

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