2010-07-14 33 views
33

我一直在逐漸學習Haskell,甚至覺得我有一堆monad。然而,我仍然有很多很難理解的奇特東西,比如Arrows,Applicative等等。雖然我從Haskell代碼中汲取了一些我見過的東西,但最好找到一個真正解釋的教程他們完全。 (好像有幾十個關於單子的教程..但是一切似乎都是在這之後完成的!)單子之後學習Haskell的下一步是什麼?

+9

你應該看看Typeclassopedia,它得到很多概念,應用型和箭頭(不知道箭頭)。你可以在[monad reader issue 13]中找到它(http://www.haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf) – 2010-07-14 14:53:10

+25

忘記異國情調的東西。編寫代碼。只有當你編寫了足夠的代碼時,你才能夠欣賞到更奇特的抽象如何提供幫助。即使如此,如果沒有'Arrows'和'Applicative',你很可能會相處得很好:GHC中有10萬行代碼,我們甚至從來沒有使用monad變換器。 – 2010-07-14 21:45:38

+4

@Simon:我理解你的觀點,但你是否真的認爲嘗試關閉對更高級抽象的好奇心是個好主意?我不親自使用Haskell來完成任務 - 我可以在Java或Ruby中更高效地工作。我使用Haskell是因爲它給了我新的思考方式。我把這張海報的問題看成是本着這種精神 - 而不是如何「相處得很好」。 – 2010-07-14 22:14:07

回答

54

這裏有一些我發現有用的資源「得到的竅門」單子後:

  • 作爲SuperBloup指出,布倫特Yorgey的Typeclassopedia是必不可少的(這實際上是蓋箭一樣) 。
  • Real World Haskell中有很多很棒的東西,可以被認爲是「monads」之後:例如,可應用的解析,monad變換器和STM。
  • 約翰休斯的"Generalizing Monads to Arrows"是一個很好的資源,教給我關於monads和關於箭頭(儘管我認爲在閱讀它時已經理解monad)。
  • "Yampa Arcade"本文是功能反應規劃的一個很好的介紹。
  • 關於家庭類型:我發現與他們合作比閱讀他們更容易。 vector-space包是一個開始的地方,或者你可以看看Oleg Kiselyov和Ken Shan的course on Haskell and natural language semantics的代碼。
  • 選擇Chris Okasaki的Purely Functional Data Structures的幾個章節,並詳細介紹它們。
  • Raymond Smullyan的To Mock a Mockingbird是一個非常容易理解的組合邏輯的介紹,它將改變您編寫Haskell的方式。
  • 閱讀GérardHuet的​​。代碼是OCaml,但在處理這類文件時,能夠將OCaml翻譯成Haskell是很有用的(也不是很難)。

最重要的是,深入瞭解您使用的任何Hackage庫的代碼。如果他們正在使用您不明白的語法或成語或擴展名進行查找,請查看它。

+3

我希望我能喜歡你的答案。 – sastanin 2010-07-14 18:31:30

+1

這些都是很好的資源,但我認爲岡崎的書可能是最基本的也是最直接有用的。 – 2010-07-15 11:54:03

+0

這裏有很多很棒的鏈接,謝謝!也請感謝其他人的回答:) – guhou 2010-07-18 10:34:29

0

編寫一個haskell編譯器:-)。

4

類型類像MonadApplicativeArrowFunctor是巨大的,所有的,更偉大的變化,你是如何看待的代碼比有通用在他們的功能的必要的便利。但是人們普遍認爲Haskell的「下一步」正在學習更多的類結構和構造控制流的方法。下一步是決定你想要寫什麼,並試着寫下來,探索你需要的東西。

即使你理解Monad,這並不意味着你已經抓住了你能用單向結構化代碼做的事情。玩解析器組合庫,或者自己寫。探索爲什麼應用符號有時更容易。探索爲什麼限制自己適用解析器可能更有效。

查看邏輯或數學問題並探索實現回溯的方法 - 深度優先,寬度優先等。探索ListT與LogicT和ChoiceT之間的區別。看看延續。

或者做一些完全不同的事!

3

你知道所有你需要去寫代碼。但是,如果你正在尋找更多的Haskell-y的東西要了解,我可以建議:

  • 類型的家庭。非常方便的功能。它基本上爲您提供了一種在類型級別編寫函數的方法,當您試圖以非常精確的方式編寫參數爲多態的函數時,這非常方便。一個這樣的例子:

 
data TTrue = TTrue 
data FFalse = FFalse

class TypeLevelIf tf a b where type If tf a b weirdIfStatement :: tf -> a -> b -> tf a b

instance TypeLevelIf TTrue a b where type If TTrue a b = a weirdIfStatement TTrue a b = a

instance TypeLevelIf FFalse a b where type If FFalse a b = b weirdIfStatement FFalse a b = a

這給了你表現得像一個if語句的功能,但能夠返回基於它被賦予的真值不同的類型。

如果您對類型級編程感到好奇,類型族爲此主題提供了一條途徑。

  • 模板哈斯克爾。這是一個很大的課題。它給你一個類似於C中的宏的能力,但是具有更多的類型安全性。

  • 瞭解一些領先的Haskell庫。我無法計算parsec能夠讓我快速寫出一個非常有用的實用程序。 dons定期在hackage上發佈流行庫的列表; check it out

4

你可以做的最重要的事情就是探索更多的Hackage。充分利用Haskell的各種奇特功能可能會讓您找到針對某些問題的改進解決方案,而Hackage上的庫將大大擴展您的工具集。

關於Haskell生態系統最好的部分是,你可以通過學習如何在Hackage上使用巨大的蜂鳴器來平衡學習外科精確的新抽象技術。

4

開始寫代碼。你會學習必要的概念。

除了語言之外,要有效地使用Haskell,您需要學習一些真實世界的工具和技巧。需要考慮的事情:

  • Cabal,一個工具來管理依賴,構建和部署應用程序的Haskell *
  • FFI(外部函數接口)使用來自Haskell代碼的C庫**
  • Hackage作爲其他人的圖書館的來源。
  • 如何到profile and optimize
  • 自動測試框架(QuickCheck,HUnit)。

*)cabal-init有助於快速啓動。

**)目前,我最喜歡的FFI綁定工具是bindings-DSL

10

關於類型類:

  • Applicative其實比Monad簡單。我最近在其他地方說過a few things about it,但其要點是它可以增強Functor,您可以將功能提升爲。爲了得到Applicative的感覺,你可以試試Parsec寫點東西而不用do表示法 - 我的經驗是應用風格比直接分析器的monadic更好。

  • Arrow s是一種非常抽象的方式來處理類似於函數(類型之間的「箭頭」)的事物。在你偶然發現一些自然而然的東西之前,他們可能很難讓你的頭腦發熱。在編寫具有反饋循環的交互式狀態機時,我重新創建了一半的Control.Arrow(糟糕的)。

  • 你沒有提到它,但一個經常被低估的,強大的類型是謙虛的Monoid。有可以找到幺山狀結構的地方有地段。例如,看看monoids package


除了類型類,我會提供一個非常簡單的回答你的問題:寫程序!最好的學習方法是通過做,所以選擇一些有趣或有用的東西,只是讓它發生。實際上,許多更抽象的概念 - 比如Arrow - 如果稍後再回過頭來發現它們會更有意義,並且發現像我一樣,它們爲遇到的問題提供了一個整潔的解決方案但甚至沒有意識到可以被抽象出來。

但是,如果你想拍攝一些特定的東西,爲什麼不看一看Functional Reactive Programming - 這是一個有很多承諾的技術家族,但有很多關於什麼是最好的方法的開放性問題要做到這一點。

+0

+1從'Monad'備份到'Applicative','Functor'和'Monoid',我建議以相反的順序(從'Monoid'開始)。 *然後*重新訪問* Monad *並簽出'Arrow'。我敢打賭你最終會更好地理解「Monad」,以便將它放到更廣泛的環境中。 「Monad」有很多不可思議的想法。它只是另一種類型,即界面加代數法則。 – Conal 2011-09-13 16:17:42

+1

@Conal:這個答案已經過了一年多了,如果有什麼事情我會事後改變,那就是更加強調'Monoid'。它可能是最簡單的結構,它真正展示了代數思維的力量,而其他許多方面則是根據monoids的變化來定義的。儘管如此,儘管在後面留下了「Arrow」,我認爲我實際上將'Category'與'Functor'或'Applicative'並列。 – 2011-09-13 16:32:50

+0

感謝您提供關於「類別」的提示。我和你在一起。簡單&一般。 – Conal 2011-09-22 02:53:12

4

作爲下一步(而不是半打「下一步」),我建議你學習編寫自己的類型類。這裏有幾個簡單的問題讓你開始:

  • 寫一些有趣的QuickCheck實例聲明。舉個例子,你想要生成某種「有趣」的隨機樹。

  • 移動到下面的小問題:定義函數/\\/complement(「和」,「或」,&「而不是」),其可以被應用於不只是布爾但任意元數的謂詞。 (如果你仔細觀察,你可以找到答案,這一個在SO)