Repository: bitemyapp/learnhaskell Branch: master Commit: 76018bdb3ec3 Files: 33 Total size: 414.2 KB Directory structure: gitextract_f3yckcep/ ├── .gitignore ├── Contributing.md ├── LICENSE ├── Makefile ├── README.md ├── coc.md ├── code_to_learn_from.md ├── dialogues.md ├── guide-de.md ├── guide-el.md ├── guide-es.md ├── guide-fr.md ├── guide-hr.md ├── guide-id.md ├── guide-it.md ├── guide-ja.md ├── guide-ko.md ├── guide-pt.md ├── guide-ro.md ├── guide-ru.md ├── guide-sr.md ├── guide-tl.md ├── guide-tr.md ├── guide-ua.md ├── guide-zh_CN.md ├── guide-zh_tw.md ├── install.md ├── libraries.md ├── rts.md ├── specific_topics-ua.md ├── specific_topics.md ├── tools.md └── write_haskell_as_fast_as_c.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .cabal-sandbox/ cabal.sandbox.config ================================================ FILE: Contributing.md ================================================ # CONTRIBUTING.md > Building the pdf requires pandoc. - Don't hyperlink anything that appears in the table-of-content. * Reason: Those links get messed up in the final pdf. - After you're done with your edits, use `make` to build the pdf and verify that everything looks nice. ## Building pdf files You can build other pdf version of the guide for languages other than english. For instance, to build the french version: make pdf-lang GUIDE_LANG=fr This will output a `tutorial-fr.pdf` file. Currently the repository provides a `guide-*.md` file for the following languages: Language | Parameter ---------: | ------------- German | `GUIDE_LANG=de` Greek | `GUIDE_LANG=el` Spanish | `GUIDE_LANG=es` French | `GUIDE_LANG=fr` Italian | `GUIDE_LANG=it` Portuguese | `GUIDE_LANG=pt` Turkish | `GUIDE_LANG=tr` Russian | `GUIDE_LANG=ru` ================================================ FILE: LICENSE ================================================ CC0 1.0 Universal Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. For more information, please see ================================================ FILE: Makefile ================================================ PANDOC = pandoc INPUT = README.md INPUT_LANG = guide-$(GUIDE_LANG).md OUTPUT = tutorial.pdf OUTPUT_LANG = tutorial-$(GUIDE_LANG).pdf TITLE = -V title=LearnHaskell AUTHOR = -V author=bitemyapp FONTSIZE = -V fontsize=12pt FONTFAMILY = -V fontfamily=sans MAINFONT= -V mainfont=Georgia PAGESIZE = -V pagesize=a4paper GEOMETRY = -V geometry=landscape VARIABLES = $(GEOMETRY) $(FONTSIZE) $(PAGESIZE) $(TITLE) $(AUTHOR) $(FONTFAMILY) $(MAINFONT) FLAGS = --normalize --smart --toc --latex-engine=xelatex $(VARIABLES) pdf: README.md $(PANDOC) -s $(INPUT) -o $(OUTPUT) $(FLAGS) --column=80 pdf-lang: guide-$(GUIDE_LANG).md $(PANDOC) -s $(INPUT_LANG) -o $(OUTPUT_LANG) $(FLAGS) --column=80 dialogues: dialogues.md $(PANDOC) -s dialogues.md -o dialogues.pdf $(FLAGS) --column=80 ================================================ FILE: README.md ================================================ # How to learn Haskell This is a recommended path for learning Haskell based on experience helping others. A list of recommendations from one of the authors of the [Haskell Book.](https://haskellbook.com) ## For non-English speakers - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### _Don't sweat the stuff you don't understand immediately_. Keep moving! ## Community Our IRC channel is `#haskell-beginners` on [Libera Chat](https://libera.chat/). IRC web client [here](https://web.libera.chat/). The haskell [mailing lists](https://wiki.haskell.org/Mailing_lists). ### Community Guidelines See [the community guidelines](coc.md) to understand the conduct that is expected in the IRC channel. You'll get a warning if you're not obviously trolling, but be aware the channel is exclusively for those learning or teaching Haskell. # Installing Haskell ## Use Stack to get going with Haskell Get [Stack](https://haskellstack.org) to get GHC installed and to build your projects. If you don't know anything about Stack and would like an overview, check out this [comprehensive Stack video tutorial](https://www.youtube.com/watch?v=sRonIB8ZStw). ## Also, DO NOT INSTALL HASKELL PLATFORM Instead of following the instructions on Haskell.org, get Stack. ### Why not platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # How should I learn Haskell? The core recommendation is to read the lectures and complete all exercises/homework for the Spring 13 version of cis1940 followed by the FP course. Both are linked below. Everything else can be considered optional and is mentioned so you know where to look. ## Haskell Programming from First Principles. [@dmvianna](https://github.com/dmvianna) wanted me to let you know that the below are just the _free_ recommended resources. If you're willing to check out a book, we heartily recommend our own [Haskell Book!](https://haskellbook.com) If you can't afford the book for any reasons, please email us using the contact information at [our support page](https://haskellbook.com/support.html). ### Haskell Book subsumes all of the primary resources recommended here ## Yorgey's cis1940 course > _Do this first_ if aren't getting the Haskell Book, this is the best _free_ introduction to Haskell. Available [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com)'s course is the best I've found so far. This course is valuable as it will not only equip you to write basic Haskell but also help you to understand parser combinators. The only reason you shouldn't start with cis1940 is if you are not a programmer or are an inexperienced one. If that's the case, start with [Thompson's book](https://www.haskellcraft.com/craft3e/Home.html) and transition to cis1940. --- ## Functional Programming course > This is the course we recommend doing after Yorgey's cis1940 course Available on github [here](https://github.com/bitemyapp/fp-course). This will reinforce and give you experience directly implementing the abstractions introduced in cis1940, this is practice which is _critical_ to becoming comfortable with everyday uses of Functor/Applicative/Monad/etc. in Haskell. Doing cis1940 and then the FP course represents the core recommendation of my guide and is how we teach everyone Haskell. --- ## Supplementary course after cis1940 and the FP course > Provides more material on intermediate topics cs240h is available online: - [Spring 14](http://www.scs.stanford.edu/14sp-cs240h/) - [Winter 16](http://www.scs.stanford.edu/16wi-cs240h/) This is [Bryan O'Sullivan](https://github.com/bos)'s online course from the class he teaches at Stanford. If you don't know who he is, take a gander at half the libraries any Haskell application ends up needing and his name is on it. Of particular note if you've already done the Yorgey course are the modules on phantom types, information flow control, language extensions, concurrency, pipes, and lenses. --- # Resources for specific topics in Haskell These resources are not vetted or tested with learners as cis1940 and FP course have been, but they're linked in [the topic listing](specific_topics.md) so you have ideas on where to begin. This includes things like intermediate/advanced concepts and subjects like tooling and text editors. ## Dialogues > Hosted in this repository [here](dialogues.md). These are actually pretty important and helpful. Look here for deep dives on a variety of topics. ================================================ FILE: coc.md ================================================ # Code of conduct [See Chris Done's post on teaching](http://chrisdone.com/posts/teaching) Be kind and courteous. Being mean or rude scares people off and makes people not want to participate. Low-effort criticism is for the benefit of the person delivering it, not the person receiving it. Don't describe things as "easy" or "trivial". You're making people feel terrible for having to work hard for their progress. Slow learners are often the most thorough learners, this is something to celebrate! No feigning surprise. Don't act surprised when somebody says they don't know something. They'll feel terrible and you've accomplished nothing except to make yourself feel sharp. No well-actually's. When someone says something that's almost - but not entirely - correct, and you say, "well, actually…" and then give a minor correction. This is especially annoying when the correction has no bearing on the actual conversation. This doesn't mean #haskell-beginners isn't about truth-seeking or that we don't care about being precise. Almost all well-actually's are about grandstanding, not truth-seeking. No back-seat driving. If you see people working through a problem, you shouldn't intermittently interject advice. Let them work it out unless someone asks for help. Avoiding interruptions is [one of the founding purposes of #haskell-beginners](http://chrisdone.com/posts/teaching). No subtle -isms. Racism, sexism, homophobia, transphobia, and other kinds of bias are not welcome and will not be tolerated. --- Guidelines by [the Recurse Center manual](https://www.recurse.com/manual). Thanks for releasing it Recurse Center. ================================================ FILE: code_to_learn_from.md ================================================ # Note! Code listed isn't necessarily complete or a usable product. The point is that the resource linked is mostly code and code that a beginner with a grasp of the basics could learn something from. # My stuff - https://github.com/bitemyapp/bloodhound Elasticsearch, mostly datatypes to describe Elasticsearch's query API and JSON parsing/generation. - https://github.com/bitemyapp/blacktip Distributed k-ordered unique id service. Directly mimicking Flake which was itself based on Snowflake. Not correct/safe as I'm not using the system's monotonic clock. # Users that write code people should learn from - https://github.com/michaelxavier - https://github.com/nikita-volkov somewhat advanced but pokes some interesting stuff # File operations - https://gist.github.com/twopoint718/cac0bbe52fd5f0d3b1be Enumerates files in a directory and organizes them by file extension - https://gist.github.com/bitemyapp/2311fcbfa152ce0980ed Filewriter example from the Haskell.org wiki I believe # Web apps - https://github.com/bitemyapp/shawty-prime This URL shortener written in Scotty is explained in detail in [Haskell Programming](https://haskellbook.com) - https://github.com/thoughtbot/carnival Yesod app. Sort of an open source clone of Disqus. # Chat ## IRC bots - https://wiki.haskell.org/Roll_your_own_IRC_bot ## Slack stuff ### Slack API client - https://hackage.haskell.org/package/slack-api ### Slack bots - https://github.com/hlian/linklater library/framework - https://github.com/twopoint718/spocks-brain example bot/app ## Chat application in Servant + React - https://github.com/farnoy/chat frontend is coffeescript, but the backend is in Haskell ================================================ FILE: dialogues.md ================================================ # Dialogues from the IRC channel or other places ## Transducers ``` 19:31 < edwardk> bitemyapp: a transducer is recognizing that the signature of foldl splits 19:31 < edwardk> :t foldl 19:31 < lambdabot> (b -> a -> b) -> b -> [a] -> b 19:31 < bitemyapp> (b -> a -> b) -> (b -> [a] -> b) ? 19:31 < dfeuer> Splits? 19:31 < edwardk> yes, now replace a and [a] with two things and quantify over the bs 19:31 < edwardk> done 19:32 < monochrom> dfeuer: do you want -O1 or -O2? 19:32 < edwardk> type Transducer x y = forall b. (b -> y -> b) -> (b -> x -> b) 19:32 < edwardk> tada transducer 19:32 < edwardk> they compose like lenses 19:32 < edwardk> nuff said 19:32 < edwardk> now the left and right are 'of the same shape 19:32 < edwardk> :t foldl.foldl 19:32 < lambdabot> (b -> a -> b) -> b -> [[a]] -> b 19:32 < edwardk> :t foldl.foldl.foldl 19:32 < lambdabot> (b -> a -> b) -> b -> [[[a]]] -> b 19:33 < edwardk> yay transducers, next? =) 19:35 < bitemyapp> dfeuer: the last definition Hickey gave of transducers was: "a transducer is just a pre-fused Kleisli arrows in the list monad" 19:35 < dfeuer> bitemyapp, yeeeeeeeeeeaaaaahhhhhh. 19:35 < bitemyapp> edwardk: ^^ does that definition make sense to you? 19:35 < mauke> I like git 19:35 < bitemyapp> tel added that there was ambient mutable state too. 19:35 < xplat> edwardk: what are some other transducers besides foldl and (flip.foldr.flip) or whatever it was? 19:36 < edwardk> xplat: you can define maps and concatmaps, etc. 19:36 < bitemyapp> I'm not entirely sure what the list monad has to do with it, for example. 19:36 < bitemyapp> since it seems to be about folding. 19:36 < edwardk> xplat: you basically just have to say how you explode 'y' into a bunch of 'b's and fold through it left to right 19:36 < edwardk> er y into a bunch of x's and fold through them left to right 19:37 < edwardk> (or is it the other way around) 19:37 < bitemyapp> I guess that could be monadic. 19:37 < bitemyapp> sorta? 19:37 < bitemyapp> you're not using join though. 19:37 < xplat> x into a bunch of ys 19:37 < bitemyapp> you'd be mapping an x -> [y] and then reducing with fold. 19:37 < bitemyapp> rather than join. 19:37 < bitemyapp> based on edwardk's casual definition. 19:37 < edwardk> @let type Transducer a b = forall r. (r -> b -> r) -> r -> a -> r 19:37 < lambdabot> Defined. 19:37 < edwardk> :t foldl :: Transducer [a] a 19:37 < lambdabot> (r -> a -> r) -> r -> [a] -> r 19:37 < xplat> bitemyapp: it's 'exploding an x into a sequence of ys' i think that brings in the list monad 19:38 < bitemyapp> xplat: yeah, that's what I meant by "I guess that could be monadic" 19:38 < bitemyapp> xplat: but the thing is, it's not really. 19:38 < bitemyapp> xplat: you just need fmap for that. 19:38 < xplat> i wonder if these things have other shapes like traversals and folds do 19:38 < bitemyapp> xplat: fmap can do x -> [y], you need monad for concatMap - ie: join 19:39 < bitemyapp> xplat: since we're not using the parts that are specific to the list monad (bind/join), it's not really about the list monadic because the reduction is whatever fold we defined. 19:39 < edwardk> :t (\f g r -> g r . f) :: (a -> b) -> Transducer a b 19:39 < lambdabot> (a -> b) -> (r -> b -> r) -> r -> a -> r 19:39 < bitemyapp> so I'm not totally convinced but I can see why the nested introduction of lists would put somebody into thinking it was about the list monad. 19:39 < edwardk> :let tmap :: (a -> b) -> Transducer a b; tmap f g r = g r . f 19:39 < edwardk> @let tmap :: (a -> b) -> Transducer a b; tmap f g r = g r . f 19:39 < lambdabot> Defined. 19:39 < Ferdirand> hmm 19:40 < edwardk> :t foldl.tmap succ 19:40 < lambdabot> Enum b1 => (b -> b1 -> b) -> b -> [b1] -> b 19:40 < Ferdirand> so what are the other interesting Transducer types, beyond Transducer a [a] ? 19:40 < xplat> Ferdirand: well, you can use foldl or foldr for any Foldable 19:40 < edwardk> :t (\f g r -> foldl g r . f) :: (a -> [b]) -> Transducer a b 19:40 < lambdabot> (a -> [b]) -> (r -> b -> r) -> r -> a -> r 19:40 < edwardk> there you get a concatMap, etc. 19:41 < edwardk> Ferdirand: work for any Foldable, etc. 19:41 < edwardk> anyways its basically just a crippled left-biased Fold 19:41 < Ferdirand> okay, but for instance, does (Transducer [a] a) corresponds to something meaningful ? 19:42 < edwardk> by biasing left it can't handle infinite cases 19:42 < edwardk> Ferdirand: sure its a function from [a] to basically [a] ;) 19:42 < xplat> so far this all seems like stuff that would work with a Fold too; is there a difference? 19:42 < edwardk> Transducer a b is a -> [b] in disguise 19:42 < edwardk> for a finite case 19:42 < edwardk> xplat: no 19:42 < edwardk> xplat: other than the fact that this version doesn't handle infinite cases 19:42 < xplat> it seems like you could get a transducer from any fold by reading it out into Endo 19:43 < edwardk> yes 19:43 < edwardk> :t foldlOf 19:43 < lambdabot> Getting (Dual (Endo r)) s a -> (r -> a -> r) -> r -> s -> r 19:43 < edwardk> yay transducer 19:43 < edwardk> next =) 19:44 < mauke> http://jlongster.com/Transducers.js--A-JavaScript-Library-for-Transformation-of-Data are these the same transducers? 19:44 < monochrom> dfeuer: OK, I use -O2, the experiment code is "f x y = quot x y + rem x y" and "g x y = q + r where (q, r) = quotRem x y". whether Int, Integer, or Integral, f and g are different in GHC core. 19:44 < edwardk> xplat: transducers themselves aren't terribly brain bending, they are just a use of the same pattern that lens uses. finding a shape that factors through (->) when something gets quantified and using (.) and id as the way to compose them 19:45 < edwardk> its nice that they've been rediscovered, but there isn't a lot of magic there ``` ## State monad vs. fold Martin: Hello all, many times I see a problem and I say to myself: "there is some state". I then play around with the state monad and often I don't get anywhere. Then at some point I realizes, that all I need is a simple fold. I don't think I ever used the state monad outside of toy examples. Can someone give me some insights when the State Monad is beneficial and where a fold is the better choice. * * * * * John Wiegley: >>>>> martin writes: > Can someone give me some insights when the State Monad is beneficial and > where a fold is the better choice. Looking at the type of a fold: ```haskell foldr :: (a -> b -> b) -> b -> [a] -> b ``` If we juggle the arguments we get: ```haskell foldr :: (a -> b -> b) -> [a] -> b -> b ``` And if we imagine State b () actions, we can directly rewrite this as: ```haskell foldrS :: (a -> State b ()) -> [a] -> State b () ``` Which generalizes to: ```haskell foldrS :: MonadState b m => (a -> m ()) -> [a] -> m () ``` Which is roughly the same thing as using mapM_ over our State monad: ```haskell mapM_ :: Monad m => (a -> m b) -> [a] -> m () ``` In other words, these two forms in our example say the same thing: ```haskell foldr f b xs execState (mapM_ f' xs) b ``` With the only difference being the types of f and f': ```haskell f : a -> b -> b f' : a -> State b () ``` The other question you asked is when to choose one over the other. Since they are equivalent, it's really up to you. I tend to prefer using a fold over State, to keep things on the level of functions and values, rather than pulling in monads and possibly monad transformers unnecessarily. But it's a very good thing to hold these isomorphisms in your mind, since you can then freely switch from one representation to another as need be. This is true of a lot of type equivalences throughout Haskell, where the more things you can see as being essentially the same, the more freedom you have to find the best abstraction for a particular context. ## On $ and . operator ```haskell doubleEveryOther :: [Integer] -> [Integer] doubleEveryOther list = reverse .doubleEveryOtherForward . reverse $ list ``` ``` 03:28 < bitemyapp> fbernier: reverse the list, double every other number, re-reverse the list. 03:28 < bitemyapp> fbernier: the "dot" operator is just function composition. 03:28 < bitemyapp> it's nothing special, just another function. 03:28 < bitemyapp> :t (.) 03:28 < lambdabot> (b -> c) -> (a -> b) -> a -> c 03:30 < bitemyapp> fbernier: the use of $ in that function is a little idiosyncratic and unnecessary, but not problematic. 03:37 < ReinH> fbernier: there's a missing space after the . is all 03:38 < ReinH> fbernier: f x = foo $ x ==> f = foo 03:39 < ReinH> so f x = foo . bar $ x ==> f = foo . bar 03:39 < bitemyapp> fbernier: I think it's just making it point-free in this case. 03:39 < bitemyapp> @pl f x = c . b . a $ x 03:39 < lambdabot> f = c . b . a 03:39 < bitemyapp> yeah, that ^^ 03:39 < bitemyapp> fbernier: identical ^^ 03:40 < ReinH> fbernier: generally, when you see a $ you can wrap the things on either side with parens and get the same expression: 03:40 < ReinH> f x = foo . bar . bazz $ x ==> f x = (foo . bar . bazz) x 03:40 < ReinH> since (x) = x, ofc 03:41 < bitemyapp> @src ($) 03:41 < lambdabot> f $ x = f x 03:41 < bitemyapp> fbernier: That's the definition of $, only other thing missing is the high precedence set for it. 03:41 < ReinH> the exception is chains of $, like foo $ bar $ baz, where you have to parenthesize in the right direction 03:41 < ReinH> or the left direction, depending on how you look at it 03:42 < bitemyapp> fbernier: http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html ctrl-f for $ to see more 03:42 < bitemyapp> fbernier: infixr 0 is the precedence, highest there is AFAIK 03:42 < bitemyapp> fbernier: the "infixr" means it's right associative 03:42 < bitemyapp> fbernier: as opposed to infixl which would mean left associative 03:43 < ReinH> bitemyapp: or lowest, depending on how you look at it. ;) 03:43 < bitemyapp> foo $ bar $ baz ~ foo (bar (baz)) 03:43 < bitemyapp> but if it was infixl 03:43 < bitemyapp> (((foo) bar) baz) ``` ## Infix operators as prefix ``` 04:12 < ReinH> all infix operators can be written prefix 04:12 < ReinH> with this one weird trick. Other haskellers hate him. 04:13 < bitemyapp> > ($) id 1 04:13 < lambdabot> 1 04:13 < bitemyapp> > id $ 1 04:13 < lambdabot> 1 04:13 < bitemyapp> > id 1 04:13 < lambdabot> 1 ``` ## Reduction, strict evaluation, ASTs, fold, reduce ``` 05:00 < ReinH> pyro-: well, "reduce" already has a typeclass, depending on what you mean 05:00 < ReinH> so does "evaluation", depending on what you mean 05:02 < pyro-> ReinH: reduce is lambda calculus under strict evaluation 05:02 < ReinH> Yep, and it's also the other thing too. 05:02 < ReinH> ;) 05:03 < pyro-> :| 05:03 < pyro-> oh, like on lists? 05:04 < mm_freak_> dealing with ASTs is a real joy in haskell, because most of the code writes itself =) ``` ## Continuation passing style, CPS transform ``` 05:10 < pyro-> now i am writing a cpsTransform function :D 05:10 < pyro-> it already works, but the current version introduces superflous continuations 05:10 < pyro-> so i am trying to fix :D 05:10 < ReinH> pyro-: Here's a CPS transform function: flip ($) 05:11 < pyro-> i will find out about flip 05:11 < ReinH> @src flip 05:11 < lambdabot> flip f x y = f y x 05:11 < ReinH> pyro-: the essence of CPS can be described as follows: 05:11 < ReinH> :t flip ($) 05:11 < lambdabot> b -> (b -> c) -> c 05:12 < ReinH> is the type of a function which takes a value and produces a suspended computation that takes a continuation and runs it against the value 05:12 < ReinH> for example: 05:12 < ReinH> > let c = flip ($) 3 in c show 05:12 < lambdabot> "3" 05:12 < ReinH> > let c = flip ($) 3 in c succ 05:12 < lambdabot> 4 05:13 < mm_freak_> direct style: f x = 3*x + 1 05:13 < mm_freak_> CPS: f x k = k (3*x + 1) 05:13 < mm_freak_> the rules are: take a continuation argument and be fully polymorphic on the result type 05:13 < mm_freak_> f :: Integer -> (Integer -> r) -> r 05:14 < mm_freak_> as long as your result type is fully polymorphic and doesn't unify with anything else in the type signature you can't do anything wrong other than to descend into an infinite recursion =) 05:14 < mm_freak_> good: (Integer -> r) -> r 05:15 < mm_freak_> bad: (Integer -> String) -> String 05:15 < mm_freak_> bad: (Num r) => (Integer -> r) -> r 05:15 < mm_freak_> bad: r -> (Integer -> r) -> r 05:15 < pyro-> but flip ($) is not what i had in mind :D 05:16 < mm_freak_> that's just one CPS transform… there are many others =) 05:16 < ReinH> No, it's probably not. 05:16 < ReinH> But other things are pretty much generalizations of that ``` ```haskell type Variable = String data Expression = Reference Variable | Lambda Variable Expression | Combination Expression Expression type Kvariable = String data Uatom = Procedure Variable Kvariable Call | Ureference Variable data Katom = Continuation Variable Call | Kreference Variable | Absorb data Call = Application Uatom Uatom Katom | Invocation Katom Uatom cpsTransform :: Expression -> Katom -> Call cpsTransform (Reference r) k = Invocation k $ Ureference r cpsTransform (Lambda p b) k = Invocation k $ Procedure p "k" $ cpsTransform b $ Kreference "k" cpsTransform (Combination a b) k = cpsTransform a $ Continuation "v" $ cpsTransform b k ``` ### Later... ``` 05:38 < ReinH> So for example, if you have an incredibly simple expression language like data Expr a = Val a | Neg a | Add a a 05:38 < ReinH> a (more) initial encoding of an expression would be Add (Val 1) (Neg (Val 1)) 05:38 < ReinH> A (more) final encoding might be (1 - 1) or even 0 05:39 < ReinH> The initial encoding generally is more flexible (you can still write a double-negation elimination rule, for instance 05:39 < ReinH> the final encoding is less flexible, but also does more work up-front 05:40 < ReinH> More initial encodings tend to force you to use quantification and type-level tricks, CPS and pre-applied functions tend to appear more in final encodings 05:40 < ReinH> An even smaller example: 05:40 < ReinH> \f z -> foldr f z [1,2,3] is a final encoding of the list [1,2,3] 05:41 < ReinH> pyro-: I'm not really a lisper, but I'm always looking for good reading material 05:41 < ReinH> for bonus points, the foldr encoding is *invertible* as well :) 05:44 < ReinH> pyro-: the relevance is that you seem to be using the cps transform in a more initial encoding than I usually see it 05:44 < ReinH> not that this is at all bad 05:46 < bitemyapp> ReinH: where does the invertibility in the final encoding come from? 05:46 < ReinH> foldr (:) [] :) 05:46 < ReinH> it's not generally so 05:46 < bitemyapp> > foldr (:) [] [1, 2, 3] 05:46 < lambdabot> [1,2,3] 05:47 < bitemyapp> I may not understand the proper meaning of invertibility in this case. 05:47 < bitemyapp> Do you mean invertibility from final to initial encoding? 05:47 < ReinH> Just that, yes 05:47 < bitemyapp> how would it get you back to final from initial? 05:47 < ReinH> I'm not sure if that's the correct term 05:47 < bitemyapp> I don't think it is, but the intent is understood and appreciated. 05:48 < bitemyapp> invertibility implies isomorphism, implies ability to go final -> initial -> final 05:48 < ReinH> well, there is an isomorphism 05:48 < bitemyapp> well, we've established final -> initial, where's initial -> final for this example? 05:49 < bitemyapp> I figured it was a morphism of some sort, but with only a final -> initial and not a way to get back, I wasn't sure which. 05:49 < ReinH> toInitial k = k (:) []; toFinal xs = \f z -> foldr f z xs 05:49 < bitemyapp> thank you :) ``` ### Something about adjunctions. I don't know. ``` 05:51 < ReinH> bitemyapp: usually one loses information going from initial to final though 05:51 < ReinH> there's probably an adjunction here 05:51 < ReinH> there's always an adjunction 05:52 < ReinH> lol of course there's an adjunction ``` ## Data structures with efficient head and tail manipulation Asker: I am teaching myself haskell. The first impression is very good. But phrase "haskell is polynomially reducible" is making me sad :(. Anyway I am trying to backport my algorithm written in C. The key to performance is to have ability to remove element from the end of a list in O(1). But the original haskell functions last and init are O(n). My questions are: 1) Is last function is something like "black box" written in C++ which perform O(1)? So I shouldn't even try to imagine some haskell O(1) equivalent. 2) Or will optimizer (llvm?) reduce init&last complexity to 1? 3) Some people suggest to use sequences package, but still how do they implement O(1) init&last sequences equivalent in haskell? * * * * * Tom Ellis: I'm rather confused about your question. If you want a Haskell data structure that supports O(1) head, tail, init and last why not indeed use Data.Sequence as has been suggested? As for how it's implemented, it uses the (very cool) fingertree datastructure. See here for more details: * * * * * Asker: Tom said that finger tree gives us O(1) on removing last element, but in haskell all data is persistent. So function should return list as is minus last element. How it could be O(1)? This is just blows my mind... My hypothesis is that somehow compiler reduces creating of a new list to just adding or removing one element. If it is not so. Then even ':' which is just adding to list head would be an O(n) operation just because it should return brand new list with one elem added. Or maybe functional approach uses pretty much different complexity metric, there copying of some structure "list" for example is just O(1)? If so then Q about compiler is still exists. * * * * * Tom Ellis: Sounds like magic doesn't it :) But no, there's no compiler magic, just an amazing datastructure. The caveat is that the complexity is amortised, not guaranteed for every operation. Have a look at the paper if you learn about how it works. It's linked from the Hackage docs. http://hackage.haskell.org/package/containers-0.2.0.1/docs/Data-Sequence.html * * * * * Asker: Jake It would be great if you give some examples when find your notebook :) And link to the book about pure functional data structures which you are talking about. Also If some "haskell.org" maintainers are here I'd like to recommend them to pay more attention to optimality/performance questions. Because almost first question which is apeared in head of standart C/C++ programmer is "Do I get same perfomance?" (even if he do not need it). Maybe some simple and cool PDF tutorial which describes why haskell could be as fast as others will be great to have. * * * * * Richard A. O'Keefe: > I am teaching myself haskell. The first impression is very good... > Anyway I am trying to backport my algorithm written in C. The key to > performance is to have ability to remove element from the end of a > list in O(1). You can't. Not in *any* programming language. That's because lists are one of many possible implementations of the "sequence" concept, and they are optimised to support some operations at the expense of others. At the beginning level, you should think of all Haskell data structures as immutable; fixed; frozen; forever unchanged. You can't even remove an element from the front of a Haskell list, at all. All you can do is to forget about the original list and concentrate on its tail. > But the original haskell functions last and init are O(n). Haskell lists are singly linked lists. Even by going to assembly code, you could not make these operations O(1) without *using a different data structure*. > My questions are: > 1) Is last function is something like "black box" written in C++ which > perform O(1)? No. > 2) Or will optimizer (llvm?) reduce init&last complexity to 1? No. > 3) Some people suggest to use sequences package, but still how do they > implement O(1) init&last sequences equivalent in haskell? Well, you could try reading Chris Okasaki's functional data structures book. There is a classic queue representation devised for Lisp last century which represents by ([a,b],[e,d,c]) so that you can push and pop at either end. When the end you are working on runs out, you reverse the other end, e.g., ([],[e,d,c]) -> ([c,d,e],[]). That can give you a queue with *amortised* constant time. (There is a technical issue which I'll avoid for now.) But let's start at the beginning. You have an interesting problem, P. You have an algorithm for it, A, written in C. You want an algorithm for it, H, written in Haskell. Your idea is to make small local syntactic changes to A to turn in into H. That's probably going to fail, because C just loves to smash things, and Haskell hates to. Maybe you should be using quite a different approach, one that would be literally unthinkable in C. After all, being able to do things that are unthinkable in C is one of the reasons for learning Haskell. Why not tell us what problem P is? * * * * * Tony Morris: data SnocList a = SnocList ([a] -> [a]) Inserts to the front and end in O(1). ### I consider the following conclusive Edward Kmett: Note: all of the options for playing with lists and queues and fingertrees come with trade-offs. Finger trees give you O(log n) appends and random access, O(1) cons/uncons/snoc/unsnoc etc. but _cost you_ infinite lists. Realtime queues give you the O(1) uncons/snoc. There are catenable output restricted deques that can preserve those and can upgrade you to O(1) append, but we've lost unsnoc and random access along the way. Skew binary random access lists give you O(log n) drop and random access and O(1) cons/uncons, but lose the infinite lists, etc. Tarjan and Mihaescu's deque may get you back worst-case bounds on more of the, but we still lose O(log n) random access and infinite lists. Difference lists give you an O(1) append, but alternating between inspection and construction can hit your asymptotics. Lists are used by default because they cleanly extend to the infinite cases, anything more clever necessarily loses some of that power. ## listen in Writer monad ``` 20:26 < ifesdjee_> hey guys, could anyone point me to the place where I could read up on how `listen` of writer monad works? 20:26 < ifesdjee_> can't understand it from type signature, don't really know wether it does what i want.. 20:30 < ReinH> :t listen 20:30 < lambdabot> MonadWriter w m => m a -> m (a, w) 20:31 < mm_freak_> ifesdjee_: try this: runWriterT (listen (tell "abc" >> tell "def") >>= liftIO . putStrLn . snd) 20:33 < mm_freak_> in any case 'listen' really just embeds a writer action and gives you access to what it produced 20:33 < ifesdjee_> most likely i misunderstood what happens in `listen`... 20:34 < ifesdjee_> i thought i could access current "state" of writer 20:34 < mm_freak_> remember that the embedded writer's log still becomes part of the overall log 20:34 < mm_freak_> execWriter (listen (tell "abc") >> tell "def") = "abcdef" 20:35 < mm_freak_> all you get is access to that "abc" from within the writer action 20:35 < ifesdjee_> yup, I see 20:35 < ifesdjee_> thank you a lot! 20:35 < mm_freak_> my pleasure 20:37 < mm_freak_> i wonder why there is no evalWriter* 20:37 < ifesdjee_> not sure, really ``` ## Introduction and origination of free monads ``` 21:32 < sclv> does anyone have a citation for the introduction of free monads? 21:33 < sclv> they’re so universally used in the literature nobody cites where they came from anymore 21:33 < sclv> in a computational context goes back to ’91 at least 21:40 < sclv> found it 21:40 < sclv> coequalizers and free triples, barr, 1970 ``` http://link.springer.com/article/10.1007%2FBF01111838#page-1 Note: Seeing a paper on free monoids dating to 1972 by Eduardo J. Dubuc. ## Rank 2 types and type inference ``` 03:13 < shachaf> dolio: Do you know what people mean when they say rank-2 types are inferrable? 03:14 < dolio> Not really. I've never taken the time to understand it. 03:16 < dolio> One reading makes no sense, I think. Because rank-2 is sufficient to lack principal types, isn't it? 03:17 < dolio> Or perhaps it isn't.... 03:17 < shachaf> Well, you can encode existentials. 03:17 < dolio> Can you? 03:17 < dolio> forall r. (forall a. a -> r) -> r 03:17 < dolio> I guess that's rank-2. 03:18 < shachaf> You can give rank-2 types to expressions like (\x -> x x) 03:18 < shachaf> What type do you pick for x? 03:19 < dolio> forall a. a -> β 03:19 < dolio> Presumably. 03:20 < shachaf> Does β mean something special here? 03:20 < dolio> It's still open. 03:20 < dolio> Greek for unification variables. 03:21 < shachaf> OK, but what type do you infer for the whole thing?03:21 < dolio> forall r. (forall a. a -> r) -> r 03:23 < dolio> (\f -> f 6) : forall r. (Int -> r) -> r 03:23 < dolio> Is that a principal type? 03:23 < shachaf> Do you allow type classes? 03:24 < dolio> People who say rank-2 is decidable certainly shouldn't be thinking about type classes. 03:24 < shachaf> I guess with impredicativity the type you gave works... Well, does it? 03:25 < dolio> Maybe rank-2 is sufficient to eliminate all ambiguities. 03:25 < dolio> Like, one common example is: [id] 03:25 < dolio> Is that forall a. [a -> a] or [forall a. a -> a] 03:25 < dolio> But, we're not talking about Haskell, we're talking about something like system f. 03:26 < dolio> So you'd have to encode. 03:26 < dolio> And: (forall r. ((forall a. a -> a) -> r -> r) -> r -> r) is rank-3. 03:27 < shachaf> I guess... 03:27 < dolio> If I had to guess, that's what the answer is. ``` - Practical type inference for arbitrary-rank types - Peyton Jones, Vytinotis, Weirich, Shields - https://stackoverflow.com/questions/9259921/haskell-existential-quantification-in-detail - http://en.wikibooks.org/wiki/Haskell/Polymorphism ## Function types and why a -> b has b^a inhabitants ``` 02:17 < bartleby> so I understand sum and product types, but why does a -> b have b^a cardinality? 02:23 < Iceland_jack> How many functions are there of type 02:23 < Iceland_jack> () -> b 02:23 < Iceland_jack> if b has 5 inhabitants? 02:23 < bartleby> 5 02:24 < Iceland_jack> which is 5^1 right? 02:24 < Iceland_jack> You'll want to look at Chris's blog: http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/ 02:24 < bartleby> yes 02:24 < bartleby> purple link, hm... I've been there, might've missed that. 02:25 < Iceland_jack> Now what about 02:25 < Iceland_jack> Bool -> b 02:25 < Iceland_jack> if b has 3 inhabitants 02:25 < Iceland_jack> You can gain your intuition by working these things out for increasingly more involved types 02:26 < bartleby> I was trying this, but it looked like a product type... I'm doing something wrong 02:26 < bartleby> let me see this case 02:26 < Iceland_jack> sure 02:27 < bartleby> wait, if I have one pattern for True and another for False, does it count as a single function? or two? 02:28 < Iceland_jack> If they're two patterns in the same function then it's the same function 02:28 < Iceland_jack> I.e. in the function definition 02:28 < Iceland_jack> f True = ... 02:28 < Iceland_jack> f False = ... 02:28 < Iceland_jack> 'f' is a single function 02:29 < Iceland_jack> and for the first ellipsis '...' you have one of three choices (b = {b1, b2, b3}) and same for the second one 02:29 < pyro-> does b^a include non total functions? 02:29 < Iceland_jack> no 02:29 < pyro-> why is that? 02:30 < Iceland_jack> Because it breaks all sorts of reasoning and makes it more complicated 02:30 < pyro-> :D 02:30 < bartleby> no? I thought that was what I was missing... 02:30 < Iceland_jack> bartleby: How many functions of type 02:30 < Iceland_jack> Bool -> () 02:31 < bartleby> yes, that's where I'm confused. I'd guess one? 02:31 < Iceland_jack> Right, because the only choice is 02:31 < Iceland_jack> fn True = () 02:31 < Iceland_jack> fn False = () 02:31 < bartleby> matching True and False, but only returning () 02:32 < Iceland_jack> so the number of function |Bool -> ()| is |()| ^ |Bool| 02:32 < Iceland_jack> |()| ^ |Bool| 02:32 < Iceland_jack> = 1 ^ 2 02:32 < Iceland_jack> = 1 02:32 < bartleby> ah, I think I get it 02:33 < Iceland_jack> And there are 2 functions from 02:33 < Iceland_jack> Bool -> () 02:33 < Iceland_jack> conversely 02:33 < Iceland_jack> oops, () -> Bool I meant 02:33 < pyro-> Just by sitting in this channel I a learning things :D bartleby, how is it that cardinality of a type has interested you? I haven't even heard the term before 02:33 < Iceland_jack> 'const False' and 'const True' respectively 02:33 < bartleby> Iceland_jack: because 2^1 02:33 < Iceland_jack> Precisely 02:34 < Iceland_jack> pyro-: You should definitely read up on the 'Algebra of Algebraic Data Types' http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/ 02:34 < pyro-> thanks 02:34 < Iceland_jack> Lated parts discuss some more advanced uses 02:34 < Iceland_jack> *Later 02:34 < bartleby> pyro-: Algebraic Data Types, means you have an algebra for dealing with them. 02:35 < Iceland_jack> Just like you knew that 02:35 < Iceland_jack> 1 + 2 = 2 + 1 02:35 < Iceland_jack> in grade school so you can know that 02:35 < Iceland_jack> Either () Bool ≅ Either Bool () 02:35 < bartleby> blowed my mind when I read about zippers, but I hadn't seen it with functions yet 02:36 < Iceland_jack> viewing (+) = Either, 1 = () and 2 = Bool 02:36 < Iceland_jack> It also means that you can define Bool as 02:36 < Iceland_jack> type Bool = Either () () 02:36 < Iceland_jack> rather than 02:36 < Iceland_jack> data Bool = False | True 02:36 < Iceland_jack> since 02:36 < Iceland_jack> 1 + 1 ≅ 2 02:37 < Iceland_jack> Given the recent pattern synonyms extensions (PatternSynonyms) you can even use the same constructors and pattern match 02:37 < pyro-> Thats interesting 02:37 < Iceland_jack> type (+) = Either 02:37 < Iceland_jack> type BOOL = () + () 02:37 < Iceland_jack> pattern TRUE = Right () :: BOOL 02:37 < Iceland_jack> pattern FALSE = Left () :: BOOL 02:38 < Iceland_jack> and then 02:38 < Iceland_jack> not :: BOOL -> BOOL 02:38 < Iceland_jack> not TRUE = FALSE 02:38 < Iceland_jack> not FALSE = TRUE 02:38 < pyro-> what abut values instead of types? 1 + 2 = 2 + 1 works for Int. what about algebra for values of other type? 02:38 < Iceland_jack> pyro-: You're not actually using numbers 02:38 < Iceland_jack> 1 is just a nice and confusing way to refer to the type () 02:38 < pyro-> i understand 02:38 < bartleby> whoa, easy there boy! I'm overheating with 2^2 here 02:38 < Iceland_jack> not the value 1 02:38 < bartleby> :-D 02:38 < pyro-> thanks 02:39 < Iceland_jack> bartleby: Slowing down :) 02:39 < pyro-> actually that i'm not using numbers is kind of the point right? 02:39 < Iceland_jack> well it makes the analogy with elementary arithmetic clearer 02:39 < bartleby> pyro-: you are counting possible values of that type 02:40 < Iceland_jack> So you can write '2' for Bool because Bool has two things 02:40 < bartleby> so Either () Bool has three because: Left (), or Right True, or Right False 02:40 < Iceland_jack> Maybe Bool would be 3 02:40 < Iceland_jack> Yes exactly 02:40 < Iceland_jack> and thus 02:40 < Iceland_jack> Either () Bool ≅ Maybe Bool 02:41 < Iceland_jack> and also 02:41 < Iceland_jack> Maybe a ≅ Either () a 02:41 < Iceland_jack> If you define 02:41 < Iceland_jack> Maybe b = 1 + b 02:41 < Iceland_jack> Either a b = a + b 02:41 < Iceland_jack> then it becomes fairly clear 02:44 < bartleby> ah, I think it clicked here. I managed to list Bool -> Bool, four different functions 02:46 < Iceland_jack> and then for Bool -> Three where |Three| = 3 you have 3 independent choices for True and False so you have 3 * 3 = 3^2 02:46 < Iceland_jack> and so forth 02:46 < Iceland_jack> hope this clears things up a bit 02:46 < bartleby> I was unsure about partial fuctions, but now it makes sense. It's just a permutations of b I think (not sure if permutation is the right word) 02:47 < bartleby> how many arrangements with `a` elements of type `b` can I make? 02:51 < bartleby> Iceland_jack: thank you. I see that I have that page bookmarked, but I think I didn't get that Functions sections at the time 02:52 < bartleby> in fact, it's still confusing... 02:52 < bartleby> "Then each of First, Second and Third can map to two possible values, and in total there are 2⋅2⋅2 = 2^3 = 8 functions of type Trio -> Bool" 02:53 < bartleby> counting like this I was only seeing First->True, First->False, Second->True, Second->False... 6, like a product 02:54 < Iceland_jack> You have to map all the values 02:54 < Iceland_jack> so the first function might be 02:54 < Iceland_jack> f1 First = False 02:54 < Iceland_jack> f1 Second = False 02:54 < Iceland_jack> f1 Third = False 02:54 < Iceland_jack> And the second function might be 02:54 < Iceland_jack> f2 First = True 02:54 < Iceland_jack> f2 Second = False 02:54 < Iceland_jack> f2 Third = False 02:54 < bartleby> yeah, I missed that. Thinking about combinations is easier IMO. True True True, True True False, ... 02:55 < bartleby> reminds me of truth tables :) 02:55 < Iceland_jack> writing False as 0 and True as 1 you get 02:55 < Iceland_jack> Trio -> Bool = { 000, 001, 010, 011, 100, 101, 110, 111 } 02:55 < Iceland_jack> with 02:55 < Iceland_jack> |Trio -> Bool| 02:56 < Iceland_jack> = |Bool| ^ |Trio| 02:56 < dibblego> a function of the type X -> Y has Y^X possibilites 02:56 < Iceland_jack> = 2 ^ 3 = 8 02:56 < Iceland_jack> right :) 02:57 < Iceland_jack> so a function from 02:57 < Iceland_jack> Trio -> Bool 02:57 < Iceland_jack> has the following implementations 02:57 < Iceland_jack> > replicateM 3 [0, 1] 02:57 < lambdabot> [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]] 02:58 < Iceland_jack> and 02:58 < Iceland_jack> Quad -> Bool 02:58 < Iceland_jack> > replicateM 4 [0, 1] -- etc. 02:58 < lambdabot> [[0,0,0,0],[0,0,0,1],[0,0,1,0],[0,0,1,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,... 02:58 < Iceland_jack> > [ length (replicateM domainSize [0,1]) | domainSize <- [0..6] ] 02:58 < lambdabot> [1,2,4,8,16,32,64] 02:59 < Iceland_jack> > [ 2^domainSize | domainSize <- [0..6] ] 02:59 < lambdabot> [1,2,4,8,16,32,64] 03:01 < bartleby> > replicateM 2 [0,1,2] 03:01 < lambdabot> [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]] 03:01 < bartleby> so that's Bool -> Trio. nice 03:01 < Iceland_jack> Which has 3^2 = 9 elements not to put too fine a point on it 03:02 * bartleby is counting subarrays 03:02 < bartleby> yup, nine 03:02 < bartleby> now it makes sense, thanks 03:04 < spion> so basically, you want the number of the possible tables, rather than the number of items in a table? 03:04 < spion> :) 03:04 < dibblego> this is why you find there are 4 implementations of (Bool -> Bool) 03:05 < Iceland_jack> yes since you can interpret each table as a function definition 03:05 < Iceland_jack> True | False 03:05 < Iceland_jack> -----+------ 03:05 < Iceland_jack> a | b 03:05 < spion> right 03:05 < Iceland_jack> and 03:05 < Iceland_jack> replicateM (length xs) xs 03:05 < Iceland_jack> should always have n^n elements given n = length xs 03:06 < Iceland_jack> can also be rewritten as 03:06 < Iceland_jack> (length >>= replicateM) xs 03:07 < Iceland_jack> > map (length . (length>>=replicateM) . flip replicate ()) [0..7] 03:07 < lambdabot> [1,1,4,27,256,3125,46656,823543] 03:07 < Iceland_jack> > [ n^n | n <- [0..7] ] 03:07 < lambdabot> [1,1,4,27,256,3125,46656,823543] ``` ## Applicative and liftA2 ``` 02:42 < dibblego> > liftA2 (+) [1,2,3] [30,40,50] 02:42 < lambdabot> [31,41,51,32,42,52,33,43,53] 02:42 < blueclaude> Thanks dibblego 02:42 < dibblego> ! [1+30,1+40,1+50,2+30,2+40,2+50,3+30,3+40,3+50] 02:43 < benzrf> blueclaude: (<*>) on the list applicative is cartesian product, but applying the first item to the second 02:43 < benzrf> > [(++"foo"), (++"bar")] <*> ["test", "othertest", "more"] 02:43 < lambdabot> ["testfoo","othertestfoo","morefoo","testbar","othertestbar","morebar"] 02:44 < dibblego> > join (Just (Just 4)) 02:44 < lambdabot> Just 4 02:44 < dibblego> > join (Just Nothing) 02:44 < lambdabot> Nothing 02:44 < benzrf> > join [] 02:45 < lambdabot> [] 02:45 < damncabbage> > [(+ 1), (+ 2)] <*> [1,2,3] 02:45 < lambdabot> [2,3,4,3,4,5] 02:45 < dibblego> Maybe is cosemimonad, but not a comonad 02:47 < dibblego> bitemyapp: [] is also cosemimonad but not comonad ``` ```haskell liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c (<*>) :: Applicative f => f (a -> b) -> f a -> f b -- by itself, cosemimonad class Functor w => extend :: (w a -> b) -> w a -> w b ``` ## RankNTypes with CPS'y example ```haskell myFunc :: (forall a. a -> (a -> a) -> a) -> Int myFunc f = f 0 (+1) -- won't work -- otherFunc :: (a -> (a -> a) -> a) -> Int -- otherFunc f = f 0 (+1) -- use: -- myFunc (flip ($)) ``` ``` 22:42 < mm_freak_> because 'f' is polymorphic, myFunc gets to apply it to its own choice of types 22:42 < mm_freak_> in particular it can make different choices in different places 22:43 < mm_freak_> the "forall" really just means that the function implicitly takes a type argument 22:44 < bitemyapp> mm_freak_: I think part of the problem is the difference between 22:44 < bitemyapp> (forall a. a -> (a -> a) -> a) -> Int 22:44 < bitemyapp> vs. 22:44 < bitemyapp> forall a. (a -> (a -> a) -> a) -> Int 22:44 < bitemyapp> yes? 22:44 < bitemyapp> the latter being implicitly the case in Haskell. 22:44 < mm_freak_> yes, but think about it… think really really simple in this case 22:45 < mm_freak_> in the former case myFunc receives a polymorphic function, so myFunc gets to choose the type 22:45 < mm_freak_> in the latter case myFunc itself is polymorphic, so the applier of myFunc gets to choose it 22:45 < mm_freak_> notice that in the former case myFunc is monomorphic! 22:46 < mm_freak_> yeah… its type isn't quantified over any type variables 22:46 < bitemyapp> mm_freak_: but the lambda passed to it is? 22:46 < mm_freak_> yeah 22:46 < bitemyapp> okay, yes. 22:46 < bitemyapp> so we're assigning/shifting around polymorphism 22:46 < bitemyapp> between the top level function the func arg 22:46 < bitemyapp> based on the ranks/nesting 22:46 < bitemyapp> / scope'ish ``` ## Functor, algebras, Coyoneda * * * * * bitemyapp edited 4 days ago | link | delete | reply I realize this is partly because the examples are in Scala, but none of this gets at what a Functor really is. Functor is an algebra. Functor is an algebra with one operation, usually called map. That one operation has a type something like: ```haskell (a -> b) -> f a -> f b ``` That one operation should respect identity: ``` map id = id ``` And that one operation should be distributive with respect to function composition: ``` map (p . q) = (map p) . (map q) ``` That’s it people. That’s it. Functor is a very weak structure. Many things can be functor. Many of those things will not look anything like a “list”, “collection”, or even a “data structure”. Understanding free objects, free versions of these algebraic structures, can lend a more faithful intuition for what these things are. Glancing at Coyoneda (the free functor) should give one some idea of why you’re not dealing with something that has anything to do with lists. Want to know more? You know the drill: https://github.com/bitemyapp/learnhaskell Edit: Since I take great satisfaction in excising misunderstandings, I’m going to include a Functor instance that should help drop the “collections” oriented view of what they are. ```haskell -- (->) or -> is the type constructor for functions -- a -> a, the identity function's type is a type of -- -> taking two parameters of the same type (a and a) -- (->) a a analogous to Either a b instance Functor ((->) r) where map = (.) -- (.) or . is function composition -- (.) :: (b -> c) -> (a -> b) -> a -> c -- more on this Functor instance: -- https://stackoverflow.com/questions/10294272/confused-about-function-as-instance-of-functor-in-haskell ``` Bonus round for upvoting me: http://www.haskellforall.com/2012/09/the-functor-design-pattern.html http://hackage.haskell.org/package/kan-extensions-3.7/docs/Data-Functor-Coyoneda.html http://oleksandrmanzyuk.wordpress.com/2013/01/18/co-yoneda-lemma/ https://www.reddit.com/r/haskell/comments/17a33g/free_functors_the_reason_free_and_operational_are/c83p8k2 https://gist.github.com/thoughtpolice/5843762 * * * * * tel 4 days ago | link | reply ``` Understanding free objects, free versions of these algebraic structures, can lend a more faithful intuition for what these things are. ``` This is a super great point—it also, meaningfully, applies to other structures like Monads, Applicatives, or Monoids, Categories, Arrows. Really quickly, here’s Yoneda and Coyoneda (the “two” free functors) ```haskell newtype Yoneda f a = Yoneda { runYoneda :: forall b . (a -> b) -> f b } data Coyoneda f b where Coyoneda :: f a -> (a -> b) -> Coyoneda f b ``` In each case we see that functor tends to mean having a parametric structure (the f) and a method of transforming the parameter to something else (the functions a -> b). When we “collapse” this free view of a functor we get to decide if, how, when, and why we combine that structure and its mapping function. For lists we, well, map it. For something like ```haskell data Liar a = Liar -- note that `a` does not appear on the right side ``` we just throw the mapping function away. (Another key point that’s a bit harder to see is that if you map the Yoneda/Coyoneda formulation repeatedly it does not store each and every mapping function but instead composes them all together and retains only that composition. This ensures that functors cannot “see” how many times fmap has been called. That would let you violate the functor laws!) * * * * * gclaramunt 3 days ago | link | reply Do you have any reference of functor being an algebra? I’m intrigued Since we’re clarifying what a functor is, I guess is worth noting that you’re talking about endofunctors in the (idealized) Hask category. In category theory, a functor is defined by two mappings: one for objects in the category and one for arrows, that must preserve identity and composition (the laws you mention). Since the mapping of objects is already given by the type constructor, here one needs to provide only the mapping of functions but it kind of irks me when ppl. say a functor is only defined by “map” :) * * * * * tel 2 days ago | link | reply Functor is definitely an algebra. Its rules mean that it has tight relation to certain functors in CT. * * * * * gclaramunt edited 2 days ago | link | reply Interesting… any refereces I can read? Or you’re talking about F-algebras? * * * * * tel 2 days ago | link | reply I mean “algebra” as “set of operations and equalities”. * * * * * gclaramunt 2 days ago | link | reply Ok. To be honest, I need to familiarize myself with the definition of algebra, is just that I had never heard this before :) * * * * * tel 1 day ago | link | reply It’s an incredibly overloaded term, tbh. In the context of abstract algebra you’d probably want to think of a (G, L)-algebra as a set inductively defined by generators G and laws L. For instance, here’s a “free” monoid algebra (note that this isn’t a free monoid, but a “free monoid algebra” or a “free algebra of the monoid type” or a “(monoid, {})-algebra” maybe) ```haskell data FMonoid where Fmempty :: FMonoid Fmappend :: FMonoid -> FMonoid -> FMonoid class Monoid FMonoid where -- this is wrong! doesn't follow laws! mempty = Fmempty mappend = Fmappend ``` note that it has all the “generators” of the typeclass Monoid but follows none of the rules (mempty <> mempty != mempty). Typically we also want to add a set of constants to form the smallest free algebra over a set ```haskell data FMonoid a where Embed :: a -> FMonoid a Fmempty :: FMonoid a Fmappend :: FMonoid a -> FMonoid a -> FMonoid a ``` * * * * * gclaramunt 1 day ago | link | reply Really interesting, thanks a lot! Now I’m trying to see how this ties to the Functor typeclass: G are the instance constructors and the functor laws make L ? I think I’m missing an important piece of the puzzle here :) * * * * * tel 1 day ago | link | reply You’re not, that’s basically it. ```haskell data FFunctor f a where EmbedFunctor :: f a -> FFunctor f a Ffmap :: (a -> b) -> FFunctor f a -> FFunctor f b ``` This lets you build the free (Functor, {})-algebra over some initial type f. If we translate it naively then it doesn’t follow the laws ```haskell class Functor (FFunctor f) where -- wrong! fmap = Ffmap ``` but we can implement it properly if we’re a little more clever ```haskell class Functor (FFunctor f) where fmap f x = case x of EmbedFunctor fa -> Ffmap f x Ffmap g fa -> Ffmap (f . g) fa ``` We need one more function, though, since we can’t use EmbedFunctor directly without exposing information about whether or not we’ve ever fmaped this functor (which shouldn’t be possible to access, that’s what fmap id = id says) ```haskell embed :: f a -> FFunctor f a embed fa = Ffmap id (EmbedFunctor fa) ``` And now, if we think about it, we can see that every value of FFunctor constructed using embed and fmap is of the form ```haskell Ffmap fun (EmbedFunctor fa) ``` And so that EmbedFunctor constructor is totally superfluous. Let’s remove it ```haskell data FFunctor f a where Ffmap :: (a -> b) -> f a -> FFunctor f b embed :: f a -> FFunctor f a embed fa = Ffmap id fa ``` And—well—this is just CoYoneda again! ```haskell lower :: Functor f => FFunctor f a -> f a lower (Ffmap f fa) = fmap f fa ``` * * * * * gclaramunt about 9 hours ago | link | reply Nice Haven’t digested it properly but I see the trick is to capture the functor with a datatype (is the same thing with free monads, right?) Now is easier to see from where CoYoneda comes, thanks! (you did show me an important piece of the puzzle :P ) ## Magma, parallelism, free monoid - [Original post](https://www.fpcomplete.com/user/bss/magma-tree) - [Guy Steele talk referenced](https://vimeo.com/6624203) - [Comment thread](https://www.reddit.com/r/haskell/comments/2corq6/algebraic_terraforming_trees_from_magma/) * * * * * edwardkmett 7 points an hour ago Much of Guy Steele's work here pertained to a desire to be able to parallelize calculation. This is a laudable goal. The main issue with a naïve magma approach Steele proposed for Fortress is that you have zero guarantees about efficient splittability. All the mass of your magma could be on one side or the other. The benefit is that without those guarantees infinite magmas make sense in a lazy language. You can have infinitely large trees just fine, that go off to infinity at any point not just at the right. This has a certain pleasing structure to it. Why? Well, lists aren't really the free monoid if you allow for infinitely recursive use of your monoid! You have unit and associativity laws and by induction you can apply them a finite number of times, but reassociating an infinite tree from the left to the right requires an infinite number of steps, taking us out of the constructive world we can program. So ultimately a free Monoid (allowing for infinite monoids) is something like Sjoerd Visscher's ```haskell newtype Free p = Free { runFree :: forall r. p r => (a -> r) -> r } type List = Free Monoid ``` Here we borrow the assumption of unit and association from the target r and generate something using it. It is an almost vacuous but now correct construction, whereas the association to the right to make a list required us to be able to right associate infinite trees. You can view this as a sort of quotient on a magma, where you guarantee to only consume it with monoidal reductions. Binding/substituting on a (unital) magma can now take longer than O(n), why? Because now I have to walk past all the structure. You can replace this with Oleg and Atze's "Reflection without Remorse", but walking down a unital Magma structure doesn't decrease n necesssarily. In the absence of infinite trees, you usually want some form of balance depending on what you want to do with the structure. e.g. turning it into a catenable deque gives you efficient access to both ends and lets you still glue in O(1) or O(log n). Switching to a finger tree gives you guaranteed O(log n) splits, but now merges go from O(1) to O(log n) In a general magma the split is potentially completely lopsided. You can 'steal work' but as often as not you likely steal a single unit, or in a unital magma, possibly nothing. The cost of these richer structures is you lose the continuous extension to the infinite case, but when trading O(n) or worse for O(log n) it is often worth making that trade-off. ## Why non-strictness (laziness) needs to be the default ``` 23:20 < slack1256> It is folklore that lazy evaluation compose better, usually showing how it supports separated generators/consumers as in "Why functional programming matters", but does this notion of composition goes further? 23:20 < Cale> slack1256: In what sense? 23:21 < slack1256> as in, if some function is not based on generator/consumer based can still benefit from laziness?. 23:21 < slack1256> (this is a problem of me having lack of imagination) 23:22 < Cale> slack1256: Most functions are consuming or generating something. Those which produce or consume larger structures with many parts that could be evaluated separately tend to benefit from laziness. 23:22 < tabemann> from what I gather, though, lazy lists aren't as useful as that paper purported 23:23 < Cale> We use them all the time 23:23 < haasn> Laziness can play well into parallelism 23:23 < haasn> Or, rather, nonstrictness 23:23 < haasn> Only evaluate the strict parts immediately, evaluate parts that don't have to be forced yet in parallel 23:23 < tabemann> what I mean is that there are better lazy sequence data structures than the list 23:23 < Cale> Oh? 23:23 < Cale> Lists are absolutely perfect for what they are 23:24 < slack1256> Mmm you're right, most functions are consuming or generating something, specially in a pure language. 23:24 < Cale> If you plan on iterating through a list of things in order, then lists present you with about as concise a representation as possible. 23:24 < Cale> slack1256: Lists are essentially our loops 23:25 < Cale> and it helps sometimes that they can be infinite, or combinatorially large 23:25 < Cale> for the same reason that you might want to have an infinite loop, or one which potentially iterates more times than you'll practically ever want to actually have the loop body occur. 23:26 < slack1256> In "more points for lazy evaluation" augustss shows that laziness enable efficient higher-order functions, and bob concedes that point that in strict languages that really hurts because you have to use manual recursion. 23:26 < Cale> yep 23:26 < slack1256> Maybe I should really learn SML to appreciate more the benefits of laziness 23:27 < josephle> then you'll lament the lack of backpack in Haskell ;) 23:28 < Cale> It really needs to be the default for that reason: if the default is to be strict, when you find the functions that you want to compose in your library, the chances are good that whoever wrote it won't have thought about your use case, and you'll need to rewrite it to be explicitly lazy, which defeats a lot of the point of having things be compositional. 23:31 < Cale> Whereas strictness is just slightly more rarely required, and tends to be the kind of thing that you can't ignore when you really need it, because your program's performance will suffer dramatically. So it just becomes a matter of learning to spot the places where it'll be important. The rule of thumb I use is this: if you're collapsing many individual bits of data down into a single thing which depends on all of them 23:31 < Cale> and can't be partially evaluated, that's where you want some sort of strict higher-order function like foldl' or some explicit strictness annotations. 23:32 < Cale> Basically, things you'd think of as accumulations of some sort. You want to avoid building up large expressions in memory composed of strict functions (functions that must pattern match on their input to produce any part of their result). 23:34 < Cale> So for instance, when you're repeatedly updating the contents of an IORef, or recursively updating an accumulating parameter without matching on it, you want to be careful there. ``` ## Functor for Reader ``` < OscarZ> instance Functor ((->) t) where < ajcoppa> OscarZ: you know about (->) from the types of functions, right? < OscarZ> ajcoppa: yes < ajcoppa> ((->) t) is a partial definition that describes a function that takes in a value of type t < OscarZ> ajcoppa: im a bit confused.. so does "instance Functor ((->) t) where" mean that were defining that any function that takes a parameter is a Functor instance? < ajcoppa> OscarZ: yep! < OscarZ> ajcoppa: is that different than saying instance Functor (a -> b) where ? < ajcoppa> OscarZ: it is different, because functors need to have a kind of * -> * < ajcoppa> as an example, when defining a functor for Optional, you don't say instance Functor (Optional Int) where -- you say instance Functor Optional where < pjdelport> OscarZ: "Functor ((->) r)" is a lot like "Functor (Either a)" and "Functor ((,) a)" < pjdelport> OscarZ: You're declaring an instance for a partially-applied type, which itself will get applied to a remaining type (which is the "slot" that the functor operates on) < pjdelport> OscarZ: So in the same sense that "instance Functor Maybe where ..." means: fmap :: (a -> b) -> Maybe a -> Maybe b < pjdelport> "instance Functor ((,) x) where ..." means: fmap (a -> b) -> (x,a) -> (x,b) < pjdelport> Or in equivalent syntax: fmap :: (a -> b) -> ((,) x) a -> ((,) x) b < pjdelport> where ((,) x) is what "f" gets replaced with < pjdelport> So for "instance Functor (Either x) where ...", you have fmap :: (a -> b) -> Either x a -> Either x b < pjdelport> and for "instance Functor ((->) r) where ...", you have fmap :: (a -> b) -> (->) r a -> (->) r b < pjdelport> or equivalently: fmap :: (a -> b) -> (r -> a) -> (r -> b) < OscarZ> oh.. i think i finally get it < pjdelport> OscarZ: To read that more intuitively, just remember what the "slot" that fmap operates on is for each Functor instance: for lists, the "slots" are all of a list's elements. For Maybe, the "slots" are Just values (if any). For Either, the "slots" are Right values. < pjdelport> OscarZ: For functions, (->), the "slot" that you're operating on is the *result* of the function. < pjdelport> So applying "fmap f" to a function value like (r -> a) uses f to "replace" the result value 'a' with a 'b', yielding a new function (r -> b). < pjdelport> (Just like how applying "fmap f" to a list value [a] uses f to "replace" each element 'a' with a 'b', yielding a new list [b].) < OscarZ> to implement Functor functions with signature a -> a -> a, should it be instance Function ((->) r t) where ? < pjdelport> OscarZ: a -> a -> a, or (a -> (a -> a)), is just a special case of (a -> b) where b = (a -> a) < OscarZ> pjdelport: so like Functor (Either a) matches (Either a) part in Either a b, Functor ((->) r) matches just the first a in a -> (a -> a) ? in this case the slot would be of type (a -> a) ? < pjdelport> OscarZ: Yep. < OscarZ> ok thanks.. i think i get.. apparently im not used to functions as first-class citizens :) somehow got confused when it was a function instead of something like Either a b < ajcoppa> it is very normal to need some time to wrap your head around this instance in particular < pjdelport> Yeah, it can be mind-bending. :) < pjdelport> but it's good exercise < OscarZ> you guys are good at explaining :) < OscarZ> you could teach FP to a rotten cabbage ``` ```haskell -- n.b. * means we're showing kind signatures, not type signatures. -- application of type arguments data (->) a b (->) :: * -> * -> * ((->) e) :: * -> * instance Functor ((->) r) where fmap = (.) instance Functor ((->) r) where fmap f g = (\x -> f (g x)) data (,) a b = (,) a b (,) :: * -> * -> * ((,) a) :: * -> * instance Functor ((,) a) where fmap f (x,y) = (x, f y) newtype Reader r a = Reader { runReader :: r -> a } Reader :: * -> * -> * (Reader r) :: * -> * instance Functor (Reader r) where fmap f m = Reader $ \r -> f (runReader m r) instance Monad (Reader r) where return a = R $ \_ -> a m >>= k = R $ \r -> runReader (k (runReader m r)) r class Functor (f :: * -> *) where fmap :: Functor f => (a -> b) -> f a -> f b class Monad (m :: * -> *) where (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a ``` ## Join for Reader ``` 18:51 < OscarZ> about join... im wondering about join (+) 7 = 14 19:14 < pjdelport> OscarZ: join for Reader becomes even more Intuitive when you pronounce Reader e a as "function from an environment e to a" 19:15 < pjdelport> Then "Reader e (Reader e a)" is just "function from an environment e to function from an environment e to a" 19:16 < pjdelport> And joining means turning that into just one "function from an environment e to a" 19:16 < pjdelport> And saying it like that should (hopefully) make the implementation and what it does more obvious :) 19:23 < pjdelport> I still think just pondering "type Reader e a = e -> a" is a great way to to get that "a ha" moment ``` ```haskell λ> join (+) 7 14 λ> join (*) 7 49 ``` ## Reversing a list operation that uses >>= SpacemanInBikini: I made a function in Haskell that takes in a number and returns a list of integers from 1 to that number. ```haskell gen x = [1..x] gen 4 -> [1, 2, 3, 4] ``` As I was learning about the monads I noticed that I could bind a list into this function as it has the type of (a -> m a). ```haskell [2, 3, 6, 1, 4] >>= gen -> [1, 2, 1, 2, 3, 1, 2, 3, 4, 5, 6, 1, 1, 2, 3, 4] ``` Then I wanted to write a function that would reverse the (>>= gen) and i came up with this function. ```haskell revgen (x:xs) = case (null xs) of False -> case ((head xs) - x) of 1 -> 1 + revgen xs otherwise -> 0 : revgen xs True -> 1 : [] ``` But it doesn't work, I think because of the revgen returning both numbers and lists. But I can't come up with a way to do this any other way with one function. Also the nested cases look ugly as hell but I quess they work as intented because at least it compiles. * * * * * meditans: Given the definitions: ```haskell gen x = [1..x] f xs = xs >>= gen ``` If you want a function g such that g . f = id, I think you could use: ```haskell g xs = map last $ groupBy (<) xs ``` ```haskell λ> groupBy (<) [1, 2, 1, 2, 3, 1, 2, 3, 4, 5, 6, 1, 1, 2, 3, 4] [[1,2],[1,2,3],[1,2,3,4,5,6],[1],[1,2,3,4]] λ> map last $ groupBy (<) [1, 2, 1, 2, 3, 1, 2, 3, 4, 5, 6, 1, 1, 2, 3, 4] [2,3,6,1,4] ``` ## Programmatically finding the inverse of a bijective function tel: If the range is finite and the domain has decidable equality ```haskell class Finite a where -- x :: a iff elem x universe = True universe :: [a] inv :: (Eq b, Finite a) => (a -> b) -> (b -> a) inv f b = let [a] = [ a | a <- universe, f a == b ] in a ``` The pattern matching above will fail if f is not bijective. ## pseq, seq, sparks ``` 16:24 < Lindrian> sparks in haskell seem so... unintuitive 16:24 < Lindrian> It doesnt really follow the traditional sense of how you use threads, which might be why I find it odd 16:25 < qu1j0t3> this might also be a very good thing :-) 16:26 < Lindrian> why? 16:28 < Lindrian> I need to remember the functionality of seq, par and pseq. 16:28 < Lindrian> seq forces evaluation of the first argument, before returning the second? par creates a "spark" that allows the first argument to be evaluated at the same time the second is being returned? 16:28 < Lindrian> I thinkkkkk 16:30 < Lindrian> damn cant remember pseq, gotta look it up 16:31 < Lindrian> oh right, pseq evaluates the left before returning the right, guaranteed. 16:32 < Lindrian> So the difference between seq and pseq is that pseq guarantees it while seq doesnt? 16:51 < qu1j0t3> well, thread API has proven to be a poor fit for many purposes. 16:53 < zwer_z> > seq (error "one") (error "two") 16:53 < lambdabot> *Exception: one 16:53 < Lindrian> > pseq (error "first") (error "second") 16:53 < lambdabot> Not in scope: ‘pseq’ 16:53 < lambdabot> Perhaps you meant ‘seq’ (imported from Prelude) 16:54 < zwer_z> IIRC in ghc seq will always evaluate to error "one", while haskell (the language) allows either 16:55 < Lindrian> i read seq as "try to evaluate the first argument, but compiler might think otherwise" 16:55 < ski> Lindrian : yes, `pseq a b' guarantees `a' is forced before `b'. `seq a b' doesn't 16:56 < ski> (i think in `seq a b' you're not even guaranteed that `a' is forced before `b' is returned .. as long as it will happen eventually) 16:56 < zwer> ski I think there's a lack of guarantee only if both a and b are bottom. 16:57 < zwer> > seq (error "foo") 10 16:57 < lambdabot> *Exception: foo 16:57 < zwer> whereas that should always evaluate to bottom 16:58 < benzrf> iirc 16:58 < ski> zwer : consider `seq (seq (error "foo") ()) (error "bar")' -- i think this can legally raise `error "bar"' 16:58 < benzrf> the haskell spec only says 16:58 < benzrf> seq bottom anything = bottom 16:58 < ski> yes 16:58 < benzrf> seq anything bottom = bottom 16:58 < zwer> ski I think so too. if b is bottom a does not have to be evaluated at all 17:00 < ski> zwer : in this case "`b'" for the inner call is not bottom 17:02 < Lindrian> so seq will try to evaluate to WHNF? 17:02 < Lindrian> pseq guarantees WHNF 17:03 < zwer> ski a is entire inner seq, which may not be evaluated 17:05 < ski> yes 17:05 < ski> (i think i used a different argument, though. i can't recall it atm) 17:06 < ski> Lindrian : both will evaluate to WHNF. `pseq' guarantees sequential *ordering*. `seq' just guarantees that both will be forced 17:07 < Lindrian> pseq guarantees the first argument is evaluated to WHNF before the second, while seq doesnt. Ok. 17:07 < ski> `seq' is specified using "denotational semantics", which only talks about the final value/denotation of an evaluation, not how you can get to it 17:08 < ski> `pseq' would need to be specified using "operational semantics", which talks in terms of rewriting steps (so there's an inherent ordering that we talk about here) 17:08 * ski nods to Lindrian ``` ================================================ FILE: guide-de.md ================================================ # Die Einführung Das ist mein empfohlener Weg Haskell zu lernen. *Beachte: Diese Einführung ist zwar in Deutsch, aber alle Referenzen sind leider noch in Englisch.* #### Denk an folgendes: *Mach dir nichts draus, wenn du etwas nicht direkt verstehst*. Einfach weiter machen. ## Community Unser IRC channel auf Freenode ist `#haskell-beginners`. IRC web client [hier](http://webchat.freenode.net/). Die Haskell [Mailing Listen](https://wiki.haskell.org/Mailing_lists). ### Community Richtlinien [Siehe Chris Done's Post über Lehre](http://chrisdone.com/posts/teaching) Sei freundlich und höflich. Unfreundlichkeit und Unhöflichkeit schreckt Leute ab, sodass sie nicht mehr mitmachen wollen. Wenn du dir keine Mühe bei deiner Kritik gibst, hilft sie der Person, die sie erhält, auch nicht. Beschreibe Dinge nicht als "einfach" oder "trivial". Leute, die hart für ihren Fortschritt arbeiten müssen, werden sich schlecht fühlen deswegen. Langsame Lerner sind meistens die sorgfältigsten, das sollte gewürdigt werden! Keine geheuchelte Überraschung. Spiele nicht überrascht, wenn jemand sagt, dass er etwas nicht weiß. Du erreichst nur, dass jemand sicht schlecht fühlt und du dich besonders toll. Kein "also, eigentlich ...". Wenn jemand etwas sagt, das nahezu richtig ist - aber nicht exakt - und du sagst, "also, eigentlich..." und gibst eine kleine Korrektur. Das ist besonders unnötig, da es keine Nutzen für die eigentlich Konversation hat. Das heißt nicht, dass die Recurse Center nicht an Richtigkeit oder Genauigkeit interessiert ist. Fast alle "also, eigentlich" sind Selbstdarstellung und keine konstruktiven Verbesserungen. Kein ständiges Reinreden. Wenn du siehst wie jemand ein Problem durcharbeitet, sollest du nicht immer wieder Vorschläge einwerfen. Lass es ihn herausfinden außer er fragt nach Hilfe. Unterbrechungen zu vermeiden ist [eine der Gründe für #haskell-beginners](http://chrisdone.com/posts/teaching). Rassismus, Sexismus, Homophobie, Transphobie und andere Arten von Vorurteilen sind nicht erwünscht und werden nicht toleriert. --- Richtlinien aus [the Recurse Center manual](https://www.recurse.com/manual). Danke für die Veröffentlichung Recurse Center. # Was sind Haskell, GHC, und Cabal? Haskell ist eine Programmiersprache, die in einem Report festgelegt wird, der letzte ist von 2010. Der Report ist [online](http://www.haskell.org/onlinereport/haskell2010/) verfügbar. ## GHC [GHC](http://www.haskell.org/ghc/) ist der beliebteste und bekannteste Weg mit Haskell zu arbeiten. Er beinhaltet einen Compiler, REPL (Interpreter), Paket Management, und ein paar weitere Dinge. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) ist für Projekt Management und Abhängigkeitsauflösung zuständig. Hiermit installierst du Projekte, normalerweise in ihre eigene Sandbox. Cabal ist äquivalent zu Rubys Bundler, Pythons pip, Nodes NPM, Maven, etc. GHC kümmert sich selber um die Paketierung, Cabal wählt die zu installierende Version aus. # Installation ## Ubuntu [Dieses PPA](http://launchpad.net/~hvr/+archive/ghc) ist ausgezeichnet und ich benutze es auf allen meine Linux Entwicklungs- und Buildmaschinen. Genauer: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.20 ghc-7.8.3 happy-1.19.4 alex-3.1.3 ``` Dann füge das folgende zu deinem `$PATH` (bash\_profile, zshrc, bashrc, etc) hinzu: ``` ~/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.8.3/bin:/opt/happy/1.19.4/bin:/opt/alex/3.1.3/bin ``` *Optional:* Du kannst auch `.cabal-sandbox/bin` zu deinem PATH hinzufügen. Code, der gerade entwickelt wird, ist dann verfügbar über die Kommandozeile. Das funktioniert aber nur, wenn das aktuelle Verzeichnis eine Cabal Sandbox ist. ## Debian ### Ubuntu PPA nutzen Wenn du nicht stable benutzt, kannst du dieselben Schritte wie unter Ubuntu ausführen, aber du musst ein weiteres Kommando ausführen. Direkt nachdem `sudo add-apt-repository -y ppa:hvr/ghc` ausgeführt wurde, starte: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` Für alle anderen Debian Versionen, ersetze einfach alle Vorkommen von `jessie` mit dem entsprechenden Versionsnamen im Kommando oben. Wenn, warum auch immer, die Datei `/etc/apt/sources.list.d/hvr-ghc-jessie.list` nicht existiert, dann sollte `/etc/apt/sources.list` eine Liste, wie die folgende beinhalten: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Ersetze `jessie` durch `trusty` in dieser Zeile. ### Manuell Kompilieren Du kannst [dieser](http://www.davesquared.net/2014/05/platformless-haskell.html) Anleitung folgen (geschrieben für Mac OS X): Anmerkungen: - Setze deinen Präfix entsprechend, wenn du GHC konfiguierst - Anstatt die `cabal-install` Binary zu laden, lade die Quellen und führe das Skript `bootstrap.sh` aus. ## Fedora 21 Um Haskell 7.8.4 aus dem unoffiziellen Repo (Fedora 22+ wird es in den offiziellen beinhalten) zu installieren: ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` Wie in auf der Seite [petersen/ghc-7.8.4 copr](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) beschrieben kann dieser ghc nicht parallel zu Fedora/EPEL ghc installiert werden. ## Arch Linux Um Haskell aus den offiziellen Repos unter Arch Linux zu installieren, mache folgendes: ```bash $ sudo pacman -S cabal-install ghc happy alex haskell-haddock-library ``` ## Gentoo Unter Gentoo kannst du verschiedene Komponenten der Haskell Platform via Portage installieren. Wenn du `ACCEPT_KEYWORDS=arch` nutzt (anstatt `ACCEPT_KEYWORDS=~arch`), installiert Portage die uralt Versionen der verschiedenen Haskell Teile. Daher füge, wenn du, und *nur* wenn du `ACCEPT_KEYWORDS=arch` nutzt, das Folgende in `/etc/portage/package.accept_keywords` ein. dev-haskell/cabal-install ~arch dev-lang/ghc ~arch Wenn das getan ist: ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo hat eine "stabile" (lies: alte) Version von `cabal-install` im Portage tree, daher wirst du `cabal-install` nutzen wollen um eine neuere version zu installieren. Beachte, dass backslashes Absicht sind. ```bash $ \cabal update # The backslashes $ \cabal install cabal-install # are intentional ``` Du hast cabal jetzt global mit Portage und lokal in deinem Home Verzeichnis mit `cabal-install` installiert. Der nächste Schritt ist sicherzustellen, dass, wenn du `cabal` im Terminal ausführst, die aktuelle Version genommen wird. Dafür kannst du folgende Zeilen zur Konfiguration deiner Shell hinzufügen: ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` Wenn du nicht weißt, was für eine Shell du nutzt, ist es mit hoher Wahrscheinlichkeit die Bash. Wenn du die Bash nutzt, musst du die Datei `~/.bashrc` editieren. Wenn du die Z-shell nutzt, ist die Datei `~/.zshrc`. Du kannst folgendes Kommando ausführen, um herauszufinden, was für eine Shell du benutzt: ```bash echo $SHELL | xargs basename ``` Ich nutze zsh, daher ist die Ausgabe `zsh`, wenn ich es ausführe. Wenn du all das getan hast, brauchst du die weiteren Tools`alex` und `happy`. ```bash $ cabal install alex happy ``` Glückwunsch! Du hast jetzt eine funktionierende Haskell installation! ## Mac OS X ### 10.9 Installiere die [GHC for Mac OS X](http://ghcformacosx.github.io/) App, welche GHC und Cabal beinhaltet. Sie liefert Anweisungen, wie du GHC und Cabal zu deinem path hinzufügen kansnt, nachdem du die `.app` irgendwo ableget hast. ### 10.6-10.8 Installiere die Binary Distribution, wie unten beschrieben, mit [diesem tarball](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2). ## Windows - Der [minimale ghc Installer für Windows](http://neilmitchell.blogspot.com/2014/12/beta-testing-windows-minimal-ghc.html) ist in der Lage `network` und andere zu installieren. Technisch gesehen befindet er sich in der Beta, sollte aber für die Zwecke eines jeden der diese Anleitung ließt funktionieren. Vergesse nicht den Installer als Administrator auszuführen, da er in deinen Programmen installieren will. ## Andere Linux Nutzer Lade die aktuellen Binary Distributions für cabal und ghc: - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). #### Detailierte Installationsanleitung für Mac OS X Du musst das nicht machen, wenn du die .app nutzt, aber wenn das für dich nicht funktioniert, versuche [das](http://www.davesquared.net/2014/05/platformless-haskell.html) mit der Binary Distribution. # Grundlegende Kurse ## Yorgey's cis1940 Kurs > *Den solltest du zuerst machen*, das ist eine erstklassige Einführung > in Haskell, die ich sehr empfehle Verfügbar [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com)s Kurs ist der beste, den ich bisher gefunden habe. Dieser Kurs ist wertvoll, da du nicht nur Grundlegendes über Haskell lernst, sondern auch lernst Parser Combinators zu verstehen. Der einzige Fall, in dem du nicht mit cis1940 anfangen solltest, ist, wenn du kein oder ein unerfahrener Programmierer bist. Wenn das der Fall ist, starte mit [Thompsons Buch](https://www.haskellcraft.com/craft3e/Home.html) und gehe über zu cis1940. --- ## FP Kurs > Das ist der Kurs, den ich nach Yorgeys cis1940 Kurs empfehle zu machen Verfügbar [hier](https://github.com/bitemyapp/fp-course) auf github Das wird dein Verständnis verbessern und dir Erfahrung mit der Implementierung der Abstraktionen geben, die in cis1940 eingeführt wurden, das ist die Praxis, die *ausschlaggebend* ist, um mit der üblichen Nutzung von Functor/Applicative/Monad/etc. in Haskell vertraut zu werden. Erst cis1940 und dann den FP Kurs zu machen, ist die wesentliche Empfehlung meiner Anleitung und ist der Weg, wie ich anderen Leuten Haskell beibringe. --- ## Deutsche Ressourcen *Anmerkung: Dieser Abschnitt wurde bei der Übersetzung eingefügt, um hilfreiche deutsche Inhalte zu verlinken* * [funktionale-programmierung.de](http://funktionale-programmierung.de/tags-archive.html#Haskell) ist ein Blog über Funktionale Programmierung im Allgemeinen, welcher auch Posts über Haskell beinhaltet. * [Skript](http://verify.rwth-aachen.de/fp14/FP14.pdf) der Vorlesung Funktionale Programmierung an der RWTH Aachen. Beinhaltet eine kurze Einführung in Haskell, sowie Kapitel über den Lambda Kalkül und Typüberprüfung und -inferenz. --- ## Zusätzliche Kurse cs240h > Stellt weiteres Material für fortgeschrittene Themen bereit Verfügbar [online](http://www.scs.stanford.edu/14sp-cs240h/). Das ist [Bryan O'Sullivan](https://github.com/bos)s online Version des Kurses, den er in Stanford unterrichtet. Wenn du nicht weißt, wer er ist, guck dir der Hälfte der Libraries an, die jede Haskell Anwendung am Ende braucht und sein Name wird dabei sein. Wenn du bereits den Yorgey Kurs gemacht hast, sind die Module über phantom types, information flow control, language extensions, concurrency, pipes, und lenses von besonderer Bedeutung. --- ## Referenz Material für die drei Kurse [Learn You a Haskell for Great Good (LYAH)](http://learnyouahaskell.com) und [Real World Haskell](http://book.realworldhaskell.org) (Danke bos!) sind online verfügbar. I empfehle RWH als Referenz (dickes Buch). Die Kapitel über Parsen und Monaden sind sehr gut, um ein Verständnis dafür zu kriegen, wofür Monaden nützlich sind. Andere Leute sagen, dass sie es oft verlinkt haben. Vermutlich eine gute Nachbereitung für die praktischen Teile nachdem du die essentiellen Sachen in Haskell verstanden hast? ### Was macht dieser `<-` / `do` / list comprehension syntaktische Zucker? Exzellenter [Artikel](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html). ### Um Listen und Fold zu verstehen - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### Um ein paar wesentliche Typ Klassen zu lernen Nützlich um `Functor`, `Applicative`, `Monad`, `Monoid` und andere Typ Klassen im Allgemeinen zu verstehen aber auch etwas Hask-bezogene Kategorien Theorie: - Die [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Die grundlegenden Haskell Fehler Meldungen verstehen - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Laziness, strictness, guarded recursion - Marlows [Buch](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) über Parallelisierung und Nebenläufigkeit hat eine der besten Einführungen über laziness und normal form, die ich finden konnte. Nutze anderes Material, wenn es nicht direkt verständlich ist. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - SO Frage '[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - [Johan Tibell](https://github.com/tibbe)s Folien von seinem Vortrag [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Kurze Demonstration ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Lies die Dokumentation und Implementierung von unsafeDupablePerformIO Kommentar auf Reddit von `glaebhoerl` Übersetzt: > Interessante Randbemerkung: GHC muss die state token Darstellung hinter > einem abstrakten IO Typ verstecken, weil der state token immer linear benutzt werden muss (nicht > dupliziert oder dropped(??)), aber das Typsystem kann das nicht erzwingen. Clean, ein andere > lazy Haskell-ähnliche Sprache, hat eindeutige Typen (die ähnliche zu Linearen Typen sind > und vermutlich anders in vielen Aspekten, die mir nicht bekannt sind), und sie stellen > World-passing(??) direkt und eine (nicht abstrakte) IO Monade nur der Einfachheit halber > bereit. Original: > Interesting side note: GHC needs to hide the state token representation behind > an abstract IO type because the state token must always be used linearly (not > duplicated or dropped), but the type system can't enforce this. Clean, another > lazy Haskell-like language, has uniqueness types (which are like linear types > and possibly different in ways I'm not aware of), and they expose the > World-passing directly and provide a (non-abstract) IO monad only for > convenience. # Monaden und Monaden Transformer (monad transformers) > Versuche nicht diese zu lernen bis du nicht Typ Klassen, Monoide, Funktoren > und Applikativen verstanden hast Implementiere die Monaden aus der Standard Bibliothek ( List, Maybe, Cont, Error, Reader, Writer, State ) für dich selbst, um sie besser zu verstehen. Dann schreibe vielleicht einen monadischen Interpreter für eine kleine Expression Sprache mit dem [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf) Paper (erwähnt in 'monad transformers' im folgenden). Mehrere Interpreter zu schreiben, indem man einfach nur die Monade ändert um die Semantik zu verändern kann helfen, zu verstehen was passiert. Zusätzlich, implementiere `Control.Monad` selbst. Funktionen wie `mapM` oder `sequence` sind gute Möglichkeiten, um zu üben, generischen monadischen Code zu schreiben. Der FP Kurs kann als Anleitung für diese Prozess genutzt werden, was auch beinhaltet eine eigene Applicative zu schreiben. Credits: - Reddit Kommentar von htmltyp und Crandom [hier](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Reddit Kommentar von jozefg [hier](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Monad transformers - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](http://catamorph.de/documents/Transformers.pdf). # Testen, Tests, Specs, generative/property testing - Dieses [Tutorial](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) von Kazu Yamamoto ist fantastisch. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Gute, einfache Bibliothek um zu lernen, wie streaming IO funktioniert im Allgemeinen, die Konzepte sind transferierbar auf Bibliotheken wie Pipes und Conduit # Parsen in Haskell - Parser combinator [tutorial](https://github.com/JakeWheat/intro_to_parsing) für Haskell mit Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Parsen und generieren von JSON Aeson ist die standard Lösung für parsen von [JSON](https://json.org) in Haskell. Verfübar über [hackage](https://hackage.haskell.org/package/aeson) und [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson tutorial](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Graph Algorithmen und Datenstrukturen - Das [fgl Paket](https://hackage.haskell.org/package/fgl) im Besonderen die puren, funktionalen kürzester Pfad [Algorithmen](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph Quellcode vom Containers Paket](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - Das [graphs Paket](https://hackage.haskell.org/package/graphs). - [SO Frage zu PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS for free](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Entwicklungsumgebung ## Emacs - [Alejandro Serrass Tutorial](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [Meine dotfiles](https://github.com/bitemyapp/dotfiles/) *Anmerkung: Dotfiles sind die Konfigurationsdateien für Shell und Editor, wie z.b. `.vimrc`* - [Chris Done's emacs Konfiuration](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim Seite im Haskell Wiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Arbeiten mit Cabal ## Cabal Leitfaden Cabal Hell war ein Problem für Haskell Nutzer vor der Einführung von Sandboxes. Eine Installation außerhalb einer sandbox wird in die user package-db installieren. Das ist *keine* gute Idee außer für grundlegende Pakete wie Cabal, alex, und happy. Nichts anderes sollte in den user oder der globalen package-db installiert sein, außer du weißt was du tust [Hier](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html) gibt es ein paar gute Praktiken um Cabal hell zu verhindern. Um mit einem Paket zu experimentieren oder ein Projekt zu starten, beginne mit `cabal sandbox init` in einem neuen Verzeichnis. Kurz gesagt: - Nutze immer Sandboxes, um neue Pakete zu installieren, neue oder existierende Projekte zu bauen oder Experimente zu starten - Nutze `cabal repl` um eine Projekt bezogene ghci Instanz zu starten Die vorgeschlagene, sandbox-basierte Methode sollte Paket Abhängigkeits Probleme vermeiden aber sie ist inkompatibel zu der Art wie die Haskell Plattform fertig gebaute Pakete bereitstellt. Wenn du momentan noch Haskell lernst und nicht verstehst wie ghc-pkg und Cabal funktionieren, *nutze nicht die Plattform* und stattdessen die Instruktionen, die zu Beginn erklärt wurden. ## Stackage Für alle Nutzer (normalerweise Yesod Nutzer), die Build Probleme haben, zieht Stackage in Erwägung: - Eine gute Zusammenfassung ist [hier](https://www.fpcomplete.com/blog/2014/05/stackage-server). Der Meinung des Authors nach, ist Stackage normalerweise nützlicher als ein `cabal freeze`. # Hoogle und Haddock ## Suche Code nach der Typ Signatur Die [Hoogle Suchmaschine](http://www.haskell.org/hoogle/) kann nach Typen suchen. Zum Beispiel, guck dir die such Resultate für `(a -> b) -> [a] -> [b]` [an](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Auch verfügbar über FPComplete [hier](https://www.fpcomplete.com/hoogle). Außerdem gibt es [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (welches standardmäßig ganz hackage durchsucht). ## Eine eigene lokale Instanz von Hoogle aufsetzen Siehe [hier](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Hackage Dokumentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Beachte, dass diese Artikel *etwas veraltet* sind: Zum Beispiel hat Hackage jetzt eine neue Info mit Dokumentations- und Build-Status. ## Was du wirklich wissen solltest Damit Haddock Dokumentation für verwandte Pakete inkludiert, musst du `documentation: True` in deiner `~/.cabal/config` setzen. Wenn es auf Standard Wert (`False`) gelassen wurde, musst du alle Pakete löschen und neu installieren bevor die Haddocks generiert werden. Die andere Sache, an die man denken sollte, ist, dass aufgrund der Art wie `$pkg` interpoliert wird *von* cabal, nicht von dir, die `html-location` und `content-location` Parameter *in Apostrophen* stehen *müssen* und in die Shell eingegeben werden oder in einem Shell Skript stehen. Sie werden nicht in einer Makefile funktionieren, da Make denken wird es seien Make Variablen. ```bash #! /usr/bin/env sh # You can write it one one line by skipping the backslashes cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Wenn du, wie ich, ein großer Fan von [TravisCI](https://travis-ci.org) bist, dann empfehle ich *sehr* [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) anzugucken für die Basis der `travis.yml` für deine Haskell Projekte. # Frontend/JavaScript Wir haben eine große Auswahl! Im Grunde gibt es drei Möglichkeiten, die ich empfehlen würde: * [Haste](http://haste-lang.org/) ein Haskell zu JavaScript Compiler - Der [Compiler](https://github.com/valderman/haste-compiler) auf github. - Eine tolle [Demo](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) von Haste mit einem Beispiel Projekt. * [GHCJS](https://github.com/ghcjs/ghcjs) - [GHCJS Einführung](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Nicht direkt Haskell, wie Haste und GHCJS, aber eine beliebte Wahl unter Haskellern - Geschrieben in und inspiriert durch Haskell - Teste Purescript in deinem Browser [hier](http://try.purescript.org/) - Gute Anleitung für [die ersten Schritte](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## Welche Frontend Sprache nutze ich? GHCJS und Haste sind beide komplett Haskell. GHCJS wird mit mehr Haskell Paketen funktionieren als Haste, aber ist egal für viele Frontend Projekte. Purescript ist kein Haskell, daher ist es nicht möglich Code direkt mit dem Backend zu teilen. GHCJS hat den größten Laufzeit Overhead mit über 100kb (luite arbeitet daran). Haste und Purescript sind vergleichbar. PureScript hat die beste JS Tooling Integration (nutzt gulp/grunt/bower), GHCJS und Haste integrieren besser mit Haskells Tooling (Cabal). Alle drei sind eine gute Wahl und werden für die meisten Frontend Projekte genügen. # Für ein tiefergehendes Verständnis für Laziness, NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## Forschungs Paper über Lazy Lambda Calculi - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Parallelisierung/Nebenläufigkeit - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929). Dieses Buch von Simon Marlow ist vermutlich das beste, was ich je gelesen habe über Parallelisierung und Nebenläufigkeit. - Ein ausführliches [Tutorial](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) über Testen & schrittweise Entwicklung einer Multi-thread Anwendung in Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses und Prisms Nachdem du vertraut bist mit Haskell, solltest du unbedingt in Betracht ziehen Lenses und Prims zu lernen, auch wenn du nur ein "Nutzer" bist. Du brauchst nicht du zu grunde liegende Kategorie zu verstehen damit es nützlich ist. Die Schwierigkeit Lens zu nutzen wird oft stark überschätzt. Jeder der vertraut ist mit Functor/Foldable/Traversable (oder nur dem ersten der drei) kann Lenses und Prisms bereits nutzen, um sein Leben leichter zu machen. Wenn du jemals etwas wie `(fmap . fmap)` gemacht hast, hast du bereits in deinem Kopf "lensing" gemacht. Ich empfehle zwei dieser Tutorials/Einführungen: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Siehe hier für weitere Informationen: [Lens Paket auf Hackage](http://hackage.haskell.org/package/lens). # Recursion Schemes Einige der verrückten \*-morphismus wörter, die du gehört hast, sind eigentlich über Rekursion. Beachte - Bevor du diese Material betrachtest, solltest du wissen, wie man foldr für Listen implementiert und mindestens eine andere Datenstruktur, wie z.B. einen Baum (folds sind Catamorphismen). Wenn du auch noch weißt, wie man ein unfold (Anamorphismus) implementiert, ist das hilfreich. Diese Material passt gut mit Traversable und Foldable zusammen. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Gute Demonstration, warum Hylomorphismus die Komposition von cata und ana ist - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - Diese Einführung ist echt gut. - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core und Performance Verbesserungen - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [Stackoverflow Frage: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Kapitel 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Typ und Kategorien Theorie > *Nicht* notwending um in Haskell zu entwickeln, nur für Interessierte! Wenn du dich mit Typ- oder Kategorien Theorie beschäftigen willst: - [Catster's Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) und [Catster's Guide 2](http://byorgey.wordpress.com/catsters-guide-2/) - Das [Haskell Wikibuch](http://en.wikibooks.org/wiki/Haskell/Category_theory) hat anschauliche Abbildungen - [Category Theory](http://www.haskell.org/haskellwiki/Category_theory) im Haskell Wiki hat auch gute Links zu anderen Ressourcen - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), beinhaltet ein paar praktische Beispiele - Pierces [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) Liste. ## Bücher - [Quora Frage: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) Kmett's recommendations - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) und [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Die Standard Bücher über Kategorien Theorie. - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) ist die beste auf Programmiersprachen fokussierte Einführung in Typentheorie, die ich gelesen habe. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Andere interessante Themen ## Parametricity, ad-hoc vs. parametric polymorphism, free theorems - [Parametricity](tony_parametricity.pdf). - [TeX Quellen](https://github.com/tonymorris/parametricity/) für den Vortrag von oben. - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial und Final, DSLs, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) nicht unbedingt relevant aber interessant. ## Comonads - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [Stackoverflow Frage: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [Stackoverflow Frage: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, eine Reihe von drei Artikeln von Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (computation) - [StackExchange Frage: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Vorlesungs Notizen eines kurzen, dreiteiligen Kurses](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Dependent typing - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) squint hard. - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # Statisch gelinkte Binaries - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Dialog > In diesem Repository zu finden, siehe [hier](dialogues.md). Die sind eigentlich sehr wichtig und hilfreich. Schaue hier für tiefere Einblicke in eine Vielzahl von Themen. ================================================ FILE: guide-el.md ================================================ ================================================ FILE: guide-es.md ================================================ # La Guía Este es el sendero que recomiendo para aprender Haskell. #### Para tener en consideración: *no te preocupes por las cosas que no entiendes de inmediato*. Continúa a pesar de ello. ## Comunidad Nuestro canal en IRC es `#haskell-beginners` en Freenode. Cliente web IRC [aquí](http://webchat.freenode.net/). La [lista de correo](https://wiki.haskell.org/Mailing_lists) de Haskell. ### Directrices de la Comunidad [Ver el post de Chris Done sobre enseñanza](http://chrisdone.com/posts/teaching) Se amable y cortés. Ser odioso y rudo ahuyenta a la gente y les desmotiva a participar. Criticar por el placer de criticar es solo benéfico para las personas que lo practican, no para los que reciben la crítica. No describas las cosas como "sencillas" o "simples". Vas a hacer sentir a las personas mal por tener que trabajar tan duro por su progreso. Los que aprenden mas lento son generalmente los mas meticulosos aprendices, ¡lo cual merece aprobación! No simules sorpresa. No actúes sorprendido cuando alguien reconoce no saber algo, eso hará sentir terrible a la persona y no obtendrás nada excepto hacerte ver sarcástico. "Mmm...no, de hecho..." Cuando alguien dice algo que es casi pero no completamente correcto y dices, "bueno...no, de hecho..." y luego das una mínima corrección, es especialmente molesto si la corrección que realizas no es lo suficientemente relevante. Esto no significa que al no hacerlo tratamos de ignorar la verdad o que no nos importa ser precisos. El punto es que casi todos los "Mmm... no, de hecho..." son fanfarronerías, no procuradores de la verdad. No seas el copiloto pesado que siempre esta dando instrucciones al conductor del vehículo.Si ves a alguien trabajando en un problema, no deberías interrumpir intermitentemente para dar consejo. Déjales trabajar hasta que pidan ayuda. Evitar interrupciones es [uno de los principios fundamentales de #haskell-beginners](http://chrisdone.com/posts/teaching). Ningún sutil -ismo. Racismo, sexismo, homofobia, transfobia u otro tipo de prejuicios no son bienvenidos y no serán tolerados. --- Directrices del [Manual de Recurse Center](https://www.recurse.com/manual). Gracias por la publicación, Recurse. # Instalación de Haskell ## Use la herramienta Stack para empezar con Haskell Instale [Stack](https://haskellstack.org) para tener el GHC (Glasgow Haskell Compiler) listo y para compilar sus proyectos. En el caso de que usted no conozca nada sobre Stack y le gustaria tener una visión general, hay un [tutorial en vídeo sobre Stack](https://www.youtube.com/watch?v=sRonIB8ZStw). ## NO INSTALE "HASKELL PLATFORM" En lugar de utilizar las instrucciones disponibles en Haskell.org, utilize Stack. ### ¿Por qué no utilizar "Haskell Platform"? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # ¿Cómo debería aprender Haskell? La recomendación principal es leer las clases y completar todos los ejercicios de la versión 13 de cis1940 seguidos por el curso FP. Los links de ambos se encuentran abajo. Todo lo demas puede ser considerado opcional y es mencionado para que así sepas donde mirar. ## Curso cis1940 de Yorgey > *Haz esto primero*, esta es la vía principal que recomendamos al ser introducido a Haskell. Disponible [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com) Este curso es el mejor que he encontrado hasta ahora. Este curso es valioso ya que no te equipara para escribir Haskell basico, sino que ademas te ayudara a entender combinatoria. La unica razón por la que no deberías empezar con cis1940 es si no eres un programador o eres uno con poca experiencia. Si ese es el caso, empieza con [El libro de Thompson (ingles)](https://www.haskellcraft.com/craft3e/Home.html) y haz la transición a cis1940. --- ## Curso FP > Este es el curso que recomendamos hacer despues del curso cis1940 de Yorgey. Disponible en github [aquí](https://github.com/bitemyapp/fp-course). Esto reforzara y te dara experiencia implementando directamente las abstracciones introducidas en cis1940, esto es practica que es *critica* para estar cada vez mas comodo con el uso diario de Functor/Aplicativo/Monada/etc en Haskell. Realizando cis1940 y luego el curso FP es la recomendación principal de mi guia y es como enseñamos Haskell a cualquier persona. --- ## Curso suplementario despues de los cursos cis1940 y FP > Proporciona mas material en temas intermediarios cs240h esta disponible [en linea](http://www.scs.stanford.edu/14sp-cs240h/). Este es el curso online de [Bryan O'Sullivan](https://github.com/bos) de la clase que el enseña en Stanford. Si no sabes quien es el, dale un vistazo a la mitad de las librerías que cualquier aplicación de Haskell necesita y veras su nombre en estas.Si ya haz hecho el curso de Yorgey te interesara particularmente los modulos de tipos fantasma, control de flujo de información, extensión del lenguaje, concurrencia, pipes, y lenses. --- # Recursos para temas especificos en Haskell Estos recursos no han sido investigados o probados con aprendices como los cursos cis1940 y FPT, pero estan listados en [la lista de temas](specific_topics.md) para que así tengas ideas de donde empezar.Esto incluye cosas como conceptos y temas intermedios/avanzados, por ejemplo herramientas y editores de texto. ## Dialogos > Alojado en este repositorio [Aquí](dialogues.md). Estos son de hecho muy importantes y de gran ayuda. Da un vistazo a estos para inmersiones profundas en una variedad de temas. ================================================ FILE: guide-fr.md ================================================ # Le Guide Ceci est ma façon recommandée d'apprendre Haskell. #### Quelque chose à garder en tête: *ne bloquez pas sur les points que vous ne comprenez pas immédiatement*. Continuez à avancer. ## Communauté Notre canal IRC est `#haskell-beginners` sur Freenode. Un client web IRC [ici](http://webchat.freenode.net/). Les [listes de diffusion](https://wiki.haskell.org/Mailing_lists) Haskell. ### Règles d'usage de la communauté [Voir le post sur l'enseignement de Chris Done](http://chrisdone.com/posts/teaching) Soyez gentils et courtois. Etre méchant ou désagréable fait peur aux autres et ne les encourage pas à participer. Une critique pour le plaisir de critiquer ne sert que la personne qui la fait, pas celle qui la reçoit. Ne décrivez pas quelque chose comme "facile" ou "trivial". Vous créeriez un malaise chez ceux qui doivent travailler plus durement pour progresser. Les personnes qui apprennent lentement sont souvent celles qui font un apprentissage plus approfondi, c'est quelque chose que nous devons célébrer et encourager ! Ne pas feindre la surprise. N'ayez pas l'air surpris lorsque quelqu'un affirme ne pas savoir quelque chose. La personne se sentira mal et vous n'aurez rien accompli mis à part flatter votre égo. Pas de "en fait…". Lorsqu'une personne dit quelque chose de presque - mais pas entièrement - correct, et vous répondez, "Ouais… en fait…" puis les corrigez. C'est particulièrement gênant lorsque la correction n'a aucune incidence sur la conversation actuelle. Cela ne signifie pas que Recurse Center ne se soucie pas de la recherche de la vérité ou que nous ne nous soucions pas d'être précis. Presque tous les "Ouais… en fait…" sont un moyen de se mettre en valeur, et non de la recherche de la vérité. Pas de conduite accompagnée. Si vous voyez des personnes buter sur un problème, vous ne devez pas immédiatement donner des conseils. Laissez travailler dessus à moins que quelqu'un demande de l'aide. Eviter les interruptions est [un des objectifs fondateurs du canal #haskell-beginners](http://chrisdone.com/posts/teaching). Pas de -ismes. Racisme, sexisme, homophobie, transphobie, et autres biais ne sont pas bienvenus et ne seront pas tolérés. --- Recommandations du [manuel de the Recurse Center](https://www.recurse.com/manual). Merci de l'avoir publié Recurse Center. # Qu'est ce que Haskell, GHC, et Cabal? Haskell est un langage de programmation, défini par une spécification, la plus récente datant de 2010. Celle-ci est disponible [en ligne](http://www.haskell.org/onlinereport/haskell2010/). ## GHC [GHC](http://www.haskell.org/ghc/) est le moyen le plus populaire de travailler avec le langage Haskell. Il inclut un compilateur, un REPL (interpréteur), la gestion de paquets, et plus encore. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) s'occupe de la gestion du projet et de la résolution des dépendances. C'est lui qui aide à l'installation de projets, typiquement dans leurs propres bac à sable. Cabal est l'équivalent de Bundler pour Ruby, de pip pour Python, de NPM pour Node, Maven, etc. GHC gère le packaging lui-même, Cabal choisit quelles versions doivent être installées. # Mise en place ## Ubuntu [Ce PPA](http://launchpad.net/~hvr/+archive/ghc) est excellent. C'est ce que j'utilise sur toutes mes machines Linux dédiées au développement. Plus précisément: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.20 ghc-7.8.3 happy-1.19.4 alex-3.1.3 ``` Après, ajoutez ce qui suit à votre `$PATH` (bash\_profile, zshrc, bashrc, etc.) : ``` ~/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.8.3/bin:/opt/happy/1.19.4/bin:/opt/alex/3.1.3/bin ``` *Optionnel:* Vous pouvez aussi ajouter `.cabal-sandbox/bin` à votre _path_. Ainsi, vous aurez accès au code que vous serez en train de développer directement en ligne de commandes. Cela ne marchera que si votre répertoire de travail actuel contient un _bac à sable_ cabal. ## Debian ### Utiliser le PPA d'Ubuntu Si vous n'utilisez pas la version stable, vous pouvez suivre les mêmes étapes que pour Ubuntu mais vous aurez besoin d'exécuter un commande supplémentaire. Immédiatement après l'exécution de `sudo add-apt-repository -y ppa:hvr/ghc`, lancez: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` Pour les autres versions de Debian, il suffit de remplacer les occurrences de `jessie` par le nom de votre version dans la commandes ci-dessus. Si, pour une raison quelconque, le fichier `/etc/apt/sources.list.d/hvr-ghc-jessie.list` n'existe pas, alors `/etc/apt/sources.list` devrait contenir une ligne de ce genre: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Remplacez alors `jessie` par `trusty` dans cette ligne. ### Compilation depuis les sources Vous pouvez suivre [ce guide](http://www.davesquared.net/2014/05/platformless-haskell.html) écrit pour Mac OS X: Notes: - Configurez votre préfixe de manière adéquate lorsque vous configurez ghc. - Au lieu de récupérer l'exécutable de `cabal-install`, récupérez les sources et ensuite lancez le script `bootstrap.sh`. ## Fedora 21 Pour installer Haskell 7.8.4 depuis le dépôt non-officiel (Fedora 22+ l'inclura dans l'officiel) : ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` Comme indiqué dans [la page copr petersen/ghc-7.8.4](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) cette version de ghc ne peut pas être installée en même temps que la version Fedora/EPEL de ghc. ## Arch Linux Pour installer Haskell depuis le dépôt officiel d'Arch Linux, lancez: ```bash $ sudo pacman -S cabal-install ghc happy alex haskell-haddock-library ``` ## Gentoo Sur Gentoo, vous pouvez installer les différents composants de la plateforme Haskell depuis Portage. Si vous utilisez `ACCEPT_KEYWORDS=arch` (par opposition à `ACCEPT_KEYWORDS=~arch`), Portage installera d'anciennes versions des différents composants Haskell. Maintenant que vous avez ça en tête, si et seulement si vous utilisez `ACCEPT_KEYWORDS=arch`, ajoutez ce qui suit à `/etc/portage/package.accept_keywords`. dev-haskell/cabal-install ~arch dev-lang/ghc ~arch Une fois que cela est fait, ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo garde une version "stable" (comprenez: vieille) de `cabal-install` dans la hiérarchie de Portage. Donc vous allez devoir utiliser `cabal-install` pour installer la dernière version. Notez que les backslashes sont intentionnels dans ce qui suit. ```bash $ \cabal update # Les backslashes $ \cabal install cabal-install # sont intentionnels ``` Vous avez maintenant installé cabal au niveau global avec portage, et dans votre répertoire personnel avec `cabal-install`. L'étape suivante est de s'assurer que quand vous lancez `cabal` dans un terminal, votre shell lancera la version à jour dans votre répertoire personnel. Vous allez donc devoir ajouter les lignes suivantes à votre fichier de configuration du shell : ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` Si vous ne savez quel est votre shell, il y a de fortes chances que ce soit Bash. Si vous utilisez Bash, le fichier à modifier est `~/.bashrc`. Si vous utilisez Z-shell, il s'agit du fichier `~/.zshrc`. Vous pouvez lancer la commande suivante pour savoir quel est votre shell : ```bash echo $SHELL | xargs basename ``` J'utilise zsh, donc cette commande renvoie `zsh` quand je la lance. Une fois que vous avez fait tout cela, vous allez devoir installer les outils complémentaires `alex` et `happy`. ```bash $ cabal install alex happy ``` Félicitations ! Vous avez maintenant une installation de Haskell en état de marche ! ## Mac OS X ### 10.9 Installez l'app [GHC pour Mac OS X](http://ghcformacosx.github.io/) qui inclus GHC et Cabal. Elle vous indiquera comment ajouter GHC et cabal à votre path après que vous ayez déposé le `.app` quelque part. ### 10.6-10.8 Faites l'installation décrite ci-dessus avec cette [archive](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2). ## Windows - L'[installeur minimal pour GHC](http://neilmitchell.blogspot.com/2014/12/beta-testing-windows-minimal-ghc.html) est capable de compiler `network` et les autres. Techniquement, il s'agit d'une beta mais cela devrait répondre au besoin de quiconque lira ce guide. N'oubliez pas de lancer l'installation en tant qu'administrateur puisque le programme cherchera à s'installer dans votre répertoire Program Files. ## Utilisateurs d'autres versions de Linux Téléchargez la dernière version des exécutables pour cabal et ghc - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). # Cours de base ## Le cours cis1940 de Yorgey > *Faites le en premier*, c'est la principale introduction à Haskell que je recommande. Disponible [en ligne](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Le cours de [Brent Yorgey](https://byorgey.wordpress.com) est le meilleur que j'ai trouvé jusque là. Ce cours vous donnera les bases pour écrire du code en Haskell mais vous aidera aussi à comprendre les combinateurs d'analyse (parser combinators). La seule raison pour laquelle vous ne devriez pas commencer avec cis1940 est si vous n'êtes pas un développeur ou inexpérimenté. Si c'est le cas, commencez par le [livre de Thompson](https://www.haskellcraft.com/craft3e/Home.html) puis enchainez avec cis1940. --- ## Le cours FP > C'est le cours que je recommande après avoir suivi le cours cis1940 de Yorgey Disponible sur github [ici](https://github.com/bitemyapp/fp-course). Ce cours va renforcer vos connaissances et vous fera acquérir de l'experience en implémentant directement les abstractions introduites dans le cis1940, c'est un exercice *capital* pour être à l'aise avec les usages habituels des Functors/Applicatives/Monades/etc. en Haskell. Suivre les cours cis1940 puis FP est la recommendation principale de mon guide et c'est comme ca que j'enseigne Haskell à tout le monde. --- ## Cours supplémentaire cs240h > Fournit plus de matière sur des sujets intermédiaires Disponible [en ligne](http://www.scs.stanford.edu/14sp-cs240h/). C'est la version en ligne du cours de [Bryan O'Sullivan](https://github.com/bos) enseigné à Stanford. Si vous ne savez qui il est, jetez un coup d'oeil à la moitié des libraries utilisées par les applications Haskell, son nom y figure. À regarder de plus près, si vous avez déjà fait le cours de Yorgey, les modules sur les types fantômes, les contrôles des flux d'informations, les extensions de language, la concurrence, les pipes, et les lenses. --- ### Que sont les sucres syntactiques `<-` / `do` / comprehension de listes ? Un [article](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html) excellent. ### Pour comprendre list et fold - [Comprendre List et Folds](http://vimeo.com/64673035) ### Pour apprendre quelques typeclasses courantes Utile pour comprendre `Functor`, `Applicative`, `Monad`, `Monoid` et autres typeclasses en général mais aussi un peu de théorie des catégories spécifique à Hask: - La [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Comprendre les messages d'erreur standards d'Haskell - [Comprendre les messages d'erreur standards](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Evaluation stricte et paresseuse, _guarded recursion_ - Le [livre](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) écrit par Marlow au sujet du parallélisme et de la concurrence est une des meilleures introduction au sujet de l'évaluation paresseuse et des formes normales que j'ai trouvé. N'hésitez pas à utiliser d'autres ressources si vous n'accrochez pas immédiatement à celle ci. - [Des points en plus pour l'evaluation paresseuse](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh ma paresse !](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Question sur SO : '[Haskell a-t-il une évaluation paresseuse ?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - les slides de [Johan Tibell](https://github.com/tibbe) tirés d'une présentation intitulée [raisonner avec l'évaluation paresseuse](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Brève démonstration ```haskell let a = 1 : a -- guarded recursion, (:) est évalué paresseusement let (v : _) = a -- et on peut lui appliquer du pattern matching > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Ordre d'évaluation et jetons d'états](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Révéler les mystères de la monade IO](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - ["instructions" du premier ordre](http://blog.jle.im/entry/first-class-statements). - [Haddocks pour System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Lisez la documentation et remarquez l'implémentation de `unsafeDupablePerformIO` Commentaire sur un fil Reddit de `glaebhoerl` : > Une intéressante note annexe: GHC a besoin de cacher la représentation du > jeton d'état derrière un type abstrait IO car le jeton d'état doit toujours > être utilisé linéairement (il ne doit pas être dupliqué ou abandonné), mais > son système de types ne peut l'imposer. Clean, un autre langage paresseux > à la Haskell, a des types uniques (qui sont des types linéaires et qui sont > peut être différents sur d'autre points que j'ignore). Ils exposent le passage > du Monde explicitement et proposent une monade IO (non-abstraite) uniquement > pour plus de commodités. # Monades et transformateurs de monades > Ne faites pas ça avant de comprendre les typeclasses, Monoid, Functor et > Applicative ! Implémenter les monades de la librairie standard (List, Maybe, Cont, Error, Reader, Writer, State) par vous-même afin de mieux les comprendre. Après, vous pouvez peut-être écrire un interpréteur monadique pour un langage avec des petites expressions en utilisant le papier sur les [transformateurs de monades étape par étape](http://catamorph.de/documents/Transformers.pdf) (mentionné dans la section "transformateurs de monades" ci-dessous). Écrire plusieurs interpréteurs en changeant juste le Monde pour changer les sémantiques peut aider à comprendre ce qui se passe. De la même manière, ré-implémenter `Control.Monad`. Des fonctions comme `mapM` ou `sequence` sont de bonnes opportunités pour s'entrainer à écrire du code monadique. Le cours du FP peut être utilisé comme un guide lors de ce processus, guide qui vous demandera également d'écrire vos propres Applicatives. Crédits: - Commentaires de htmltyp et Crandom sur Reddit [ici](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Commentaire de jozefg [ici](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). # Test, spécifications, tests de propriétés (tests par génération) - Ce [tutoriel](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) de Kazu Yamamoto est fantastique. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Une bonne librairie simple pour apprendre comment le streaming d'IO fonctionne en général. Les connaissances acquises ici sont transférables à Pipes et Conduit. # Parsing en Haskell - [Tutoriel](https://github.com/JakeWheat/intro_to_parsing) sur les parser combinators en Haskell utilisant Parsec. - [Ecrivez votre propre micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Parsing et génération de JSON Aeson est la solution standard de parsing de [JSON](https://json.org) en haskell. Disponible sur [hackage](https://hackage.haskell.org/package/aeson) et [github](https://github.com/bos/aeson). - [Parser du JSON avec Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson et les types personalisés](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parser des données non-deterministiques avec aeson et les types sum](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [tutoriel Aeson](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Algorithmes de graphes et structures de données - Le [package fgl](https://hackage.haskell.org/package/fgl) en particulier le plus court chemin purement fonctionnel [algos](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Graphes inductifs et Algorithmes de Graphes Fonctionnels](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - Une bibliothèque de Graphes Fonctionnels](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [source de Data.Graph extraite du package Containers](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - Le [package graphs](https://hackage.haskell.org/package/graphs). - [une question SO sur PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [un article sur PHOAS](https://www.fpcomplete.com/user/edwardk/phoas). - [Attacher le noeud](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Environment de développement ## Emacs - [le tutoriel d'Alejandro Serras](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [Mes dotfiles](https://github.com/bitemyapp/dotfiles/) - [la config emacs de Chris Done](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [la page Vim sur haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [plugin vim GHC-Mod](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Utilisation de Cabal ## Recommandations pour Cabal L'enfer de Cabal était un problème pour les utilisateurs d'Haskell avant l'introduction des bacs à sable. Une installation en dehors d'un bac à sable se fera dans le package-db de l'utilisateur. Ce n'est *pas* une bonne idée mis à part pour quelques librairies fondamentales comme Cabal, alex, et happy. Rien d'autre ne devrait être installé dans le package-db de l'utilisateur ou le global à moins que vous ne sachiez ce que vous faites. Quelques bonnes pratiques pour éviter l'enfer de cabal sont disponibles [ici](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). Pour faire des expérimentation avec un package ou démarrer un projet, commencez par `cabal sandbox init` dans un nouveau dossier. Pour résumer: - Toujours utiliser des bacs à sable pour installer de nouveaux packages, créer des projets, ou démarrer des experimentations - Utiliser `cabal repl` pour démarrer une instance ghci dans un projet L'approche basée sur les bacs à sable que je suggère permet d'éviter les problèmes liés à la gestion des dépendances des packages, mais elle n'est pas compatible avec les packages pré-construits fournis par Haskell Platform. Si vous apprenez Haskell et ne comprenez pas comment ghc-pkg et Cabal fonctionnent, *évitez platform* et utilisez les instructions préalables du guide à la place. ## Stackage Pour les utilisateurs (de Yesod généralement) qui ont des problèmes de build, considérez Stackage. - Un bon résumé de ce qu'est Stackage [ici](https://www.fpcomplete.com/blog/2014/05/stackage-server). L'auteur estime que Stackage est généralement plus utile que `cabal freeze`. # Hoogle et Haddock ## Chercher du code à partir de la signature des types Le [moteur de recherche Hoogle](http://www.haskell.org/hoogle/) permet des recherches par type. Par exemple, le résultat d'une recherche avec `(a -> b) -> [a] -> [b]` sont disponibles [ici](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Hoogle est également hébergé par fpcomplete [ici](https://www.fpcomplete.com/hoogle). Il existe aussi [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (qui contient tout hackage par défaut). ## Mettre en place propre instance local de Hoogle Vous pouvez regarder [ici](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Réparer votre documentation Hackage](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [La v2 de la documentation de Hackage](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Notez que ces billets sont *légèrement obsolètes*: par exemple, Hackage contient maintenant de nouvelles informations concernant la documentation et le statut du build. ## Ce que vous avez vraiment besoin de savoir Afin qu'Haddock inclue la documentation des paquets référencés, vous devez mettre `documentation: True` dans votre `~/.cabal/config`. Si vous avez laissé la valeur par défaut (`False`) ou l'avez délibérément définie comme `False`, vous devrez supprimer tous vos paquets et les réinstaller avant de générer des haddocks. Une autre chose que vous devez garder en tête est que comme le paramètre `$pkg` est interprété *par* cabal, et non par vous, les paramètres `html-location` et `content-location` *doivent être entourés de guillemets simples* et entrés dans un shell ou contenus dans un script shell. Ils ne fonctionneront pas dans un Makefile, car on pensera alors qu'il s'agit de variables pour Make. ```bash #! /usr/bin/env sh # Vous pouvez écrire ceci ligne par ligne en omettant les backslashes cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Si vous êtes comme moi un grand fan de [TravisCI](https://travis-ci.org), je vous recommande alors *fortement* de jeter un oeil à [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) pour avoir une base de fichier `travis.yml` pour vos projets Haskell. # Frontend/JavaScript Nous avons des problèmes de riches ! Voilà les trois principaux choix que je peux recommander: * [Haste](http://haste-lang.org/) un compilateur de Haskell vers JavaScript - Le [compilateur](https://github.com/valderman/haste-compiler) sur github. - Une excellente [démo](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) de Haste avec un exemple de projet. * [GHCJS](https://github.com/ghcjs/ghcjs) - [Introduction à GHCJS](http://weblog.luite.com/wordpress/?p=14) - [Des interfaces web réactives avec GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Écrire des extensions Atom en Haskell en utilisant ghcjs](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Pas strictement du Haskell comme Haste and GHCJS, mais un choix populaire chez les Haskellers. - Écrit en et inspiré par Haskell. - Essayez PureScript dans votre navigateur [ici](http://try.purescript.org/) - Un très bon guide pour [démarrer](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## Quel langage frontend utiliser ? GHCJS et Haste sont tous deux du pur Haskell. GHCJS marchera avec de plus nombreux paquets Haskell que Haste, mais cela n'impacte pas un grand nombre de projets frontend. PureScript n'est pas du tout du Haskell, donc un partage direct du code avec votre backend ne fonctionnera pas. GHCJS a le plus gros coût en terme de poids, avec environ 100ko (Luite travaille sur ce point). Haste et PureScript sont compétitifs. PureScript a la meilleure intégration dans la suite d'outils javascript (il utilise gulp/grunt/bower), GHCJS et Haste s'intègrent mieux avec les outils Haskell (Cabal). Les trois sont de très bons choix et sont adaptés à la plupart des projets frontend. # Pour mieux comprendre l'évaluation paresseuse, NF, WHNF - [Notes sur lambda-calcul](https://vec.io/posts/notes-on-lambda-calculus). ## Documents de recherche sur le lambda-calcul paresseux - [La nécessité du lambda-calcul](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Démonstration de la réduction avec lambda-calcul](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [Le lambda-calcul paresseux](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Evaluation paresseuse en Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Parallelisme / Concurrence - [Programmation Parallele et Concurrente en Haskell](http://chimera.labs.oreilly.com/books/1230000000929) Ce livre de Simon Marlow est probablement le meilleur que j'ai lu sur le sujet du parallélisme et de la concurrence. - Un [pas à pas](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) complet sur les tests et le développement incrémental d'une application multi-threadée en Haskell. - [Programmation Fonctionnelle Réactive](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses et Prisms Une fois que êtes confortables avec Haskell, vous devriez considérer fortement l'apprentissage des Lenses et Prisms, même en tant que simple "utilisateur". Vous n'avez pas besoin de comprendre la catégorie sous-jascente pour que cela vous soit utile. Les gens sur-estiment grandement la difficulté d'utiliser les Lens. Quiconque confortable avec Functor/Foldable/Traversable (ou juste le premier) peux utiliser les lenses et prisms et se simplifier la vie. Si vous avez déjà fait quelque chose comme: `(fmap . fmap)` vous étiez en train de "lenser" dans votre tête. Je recommande ces deux tutoriels / introductions: - [Un petit tutoriel sur Lens pour commencer](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds et Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Regardez ici pour plus d'informations: [Lens package on hackage](http://hackage.haskell.org/package/lens). # Schémas de récursion Certains des mots en \*-morphisme dont vous avez entendu parler jusque là renvoient à la récursion. NB - avant de vous attaquer à la suite vous devriez savoir comment implementer foldr pour des listes et au moins une autre structure de données, comme les arbres. (les folds sont des catamorphismes) Savoir comment implementer un unfold (anamorphisme) pour les même structures devrait clarifier un peu les choses. Ces documents se limitent aux traversables et foldables. - [Une introduction aux schémas de récursion](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [N'ayez pas peur du chat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) (un jeu de mot entre "cat" (chat) et le prefixe cata) - Une bonne démonstration sur comment l'hylomorphisme est une composition de cata et ana. - [Schémas de Récursion](http://comonad.com/reader/2009/recursion-schemes/) - Ce guide pratique est excellent. - [Programmation Fonctionnelle avec des Bananes, des Lenses, des Enveloppes et du Fil barbelé](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphismes](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core et tuning de performance - [Ecrire du Haskell aussi rapide que du C](write_haskell_as_fast_as_c.md) - [GHC Wiki: le Type CoreSyn](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [Question sur SO: Lire GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell aussi rapide que du C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapitre 25: Profilage and Optimisations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Type et Théorie des Catégories > *Pas* nécessaire pour écrire du Haskell, juste pour ceux intéressés ! Si vous voulez en apprendre plus sur les types et la théorie des catégories: - [Le guide de Catster](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) et [Le guide de Catster 2](http://byorgey.wordpress.com/catsters-guide-2/) - Le [wikibook haskell](http://en.wikibooks.org/wiki/Haskell/Category_theory) a de beaux diagrammes. - [Théorie des Catégories](http://www.haskell.org/haskellwiki/Category_theory) sur haskellwiki, dispose de bons liens vers d'autres ressources. - [Categories à partir de rien](http://science.raphael.poss.name/categories-from-scratch.html), inclus des exemples concrets. - La liste [Superbes travaux sur les languages de programmation](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) de Pierce. ## Livres - [Question sur Quora: Quel est le meilleur livre sur la théorie des catégories ?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) les recommandations de Kmett - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) et [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Les livres de référence sur la théorie des catégories. - [Fondations Pratiques pour les Languages de Programmation de Harper](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) est la meilleure introduction à la théorie des catégories d'un point de vue des languages de programmation. - [La théorie des Types et la Programmation Functionnelle](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Autres sujets amusants ## Paramétricité, ad-hoc vs. polymorphisme paramétrique, théorèmes libres - [Paramétricité](tony_parametricity.pdf). - [Les sources TeX](https://github.com/tonymorris/parametricity/) du talk ci-dessus. - [Rendre le polymorphisme ad-hoc moins ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Théorèmes gratuits !](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial et Final, les DSL, Finally Tagless - [Encodages finaux, Partie 1: Une Démonstration rapide](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transformer des valeurs Polymorphiques](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [Les GADT en Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Lambda-calcul linéaire Typed Tagless-Final](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Interprétations de Typed tagless-final: notes de Lecture](http://okmij.org/ftp/tagless-final/course/course.html). - [Les interpréteurs Typed Tagless Final](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [Le chien qui n'aboyait pas](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) moins spécifique mais intéressant tout de même. ## Co-monades - [Co-monades en Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [question sur SO: Est-ce qu'une monade peut être une co-monade ?](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / Co-Yoneda - [question sur SO: explication pas-à-pas de co-yoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, une séquence de trois articles par Edward Kmett * [Partie 1: Co-densité](http://comonad.com/reader/2011/free-monads-for-less/). * [Partie 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Partie 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Jugements (informatique) - [une question sur StackExchange: Quelle est la difference entre les propositions et les jugements ?](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Notes de lecture d'un petit cours de trois lectures](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Typage Dépendent - [Intégrer les type sum, les value constructors, et les type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html). - [Programmation légère avec typage dépendant](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Le language de programmation Idris](http://www.idris-lang.org/). # Interconnexion de binaires statique - [Interconnexion statique](https://wiki.haskell.org/Web/Literature/Static_linking) - [Interconnexion statique avec GHC sur Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Interconnexion statique de binaires Linux pour ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Interconnexion statique GMP avec GHC et LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Dialogues > Hébergés dans un dépôt [ici](dialogues.md). Ils sont importants et utiles. A regarder pour une compréhension approfondie sur des sujets variés. ================================================ FILE: guide-hr.md ================================================ # Kako naučiti Haskell Ovo je preporučeni put za učenje Haskella zasnovan na iskustvu u pomaganju drugim ljudima. Ovo je lista preporuka jednog od autora [Haskell knjige](https://haskellbook.com) ## Za one koji ne govore Hrvatski - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Ne obraćajte mnogo pažnje na stvari koje iz prve ne razumijete*. Samo idite naprijed! ## Zajednica Naš IRC kanal je `#haskell-beginners` na Freenodeu. IRC web [klijent](http://webchat.freenode.net/). Haskell [email lista](https://wiki.haskell.org/Mailing_lists). ### Smjernice zajednice Pogledajte [smjernice zajednice](coc.md) da bi razumjeli kakvo ponašanje se očekuje na IRC kanalu. Bit ćete upozoreni ako očigledno "trolate" , ali budite svjesni toga da kanal služi isključivo onima koji uče ili podučavaju Haskell. # Instaliranje Haskella ## Koristite Stack da biste krenuli sa Haskellom Preuzmite [Stack](https://haskellstack.org) da bi uz pomoć njega instalirali GHC za gradnju projekata. Ako ne znate ništa o Stacku a željeli biste saznati, pogledajte ovaj [Stack video tutorial](https://www.youtube.com/watch?v=sRonIB8ZStw). ## Također, NEMOJTE INSTALIRATI HASKELL PLATFORMU Umjesto da pratite uputstva sa Haskell.org instalirajte Stack. ### Zašto ne platforma ? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Kako da naučim Haskell? Glavna preporuka je da pročitate lekcije i završite sve vježbe iz Spring 13 verzije cis1940 tečaja nakon kojega ide FP tečaj. Oba linka su ispod. Sve ostalo može se smatrati opcionalnim i spomenuto je ovdje da biste znali gdje da tražite resurse. ## Alternativno... [@dmvianna](https://github.com/dmvianna) je željela da napomenem da su ovo samo besplatni i preporučeni resursi, ako ste zainteresirani da pogledate knjigu preporučujemo od sveg srca našu [Haskell Knjigu!](https://haskellbook.com) Ova knjiga zamjenjuje sve spomenuto. ## Yorgeyjev cis1940 tečaj > *Pročitajte ovo prvo*, ovo je primarni način koji preporučujemo za upoznavanje sa Haskellom Dostupno [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com)jev tečaj je najbolji tečaj koji sam vidio do sada. Ovaj tečaj je vrijedan zato što ne samo da će Vas pripremiti da pišete osnovni Haskell već će Vam i pomoći da razumijete parser kombinatore. Jedini razlog da ne počnete sa cis1940 tečajem je ako niste programer ili ste programer sa malo iskustva. U tom slučaju počnite sa [Thompsonovom knjigom](https://www.haskellcraft.com/craft3e/Home.html) i nakon nje prijeđite na cis1940. --- ## FP tečaj > Ovo je tečaj koji preporučujemo nakon Yorgeyjevog cis1940 tečaja Dostupan je na [githubu](https://github.com/bitemyapp/fp-course). On će utvrditi iskustvo u direktnom implementiranju apstrakcija koje su uvedene u cis1940 tečaju. Ovo je praksa koja je *kritična* da bi se osjećali ugodno sa svakodnevnom upotrebom Fanktora/Aplikativa/Monada itd. u Haskellu. Glavna preporuka ovog vodiča je da prijeđete cis1940 a zatim FP tečaj i to je način na koji učimo Haskell sve zainteresirane. --- ## Dodatni tečaj nakon cis1940 i FP > Sadrži više materijala o srednje naprednim temama cs240h je dostupan [online](http://www.scs.stanford.edu/14sp-cs240h/). Ovo je [Bryan O'Sullivan](https://github.com/bos)ov online tečaj kojim on predaje na Stanfordu. Ako ne znate tko je on bacite oko i vidjet ćete da je njegovo ime na pola Haskell biblioteka koje su potrebne bilo kojem Haskell programu. Naročito treba spomenuti, ako ste već završili Yorgeyjev tečaj, module sa fantomskim tipovima, kontrola toka informacija, ekstenzije jezika, konkurentnost, pipes i lenses biblioteke. --- # Resursi za specifične teme u Haskellu Ovi resursi nisu testirani sa učenicima kao što su tečajevi cis1940 i FP ali se nalaze u [listingu tema](specific_topics.md) tako da imate ideju odakle krenuti. Ovo uključuje srednje/napredne koncepte i teme kao što su alati i tekst editori. ## Dijalozi > Nalaze se u ovom [repozitoriju](dialogues.md). Ovo je naročito važno i korisno. Ovo je dublji pregled različitih tema. ================================================ FILE: guide-id.md ================================================ # Bagaimana cara belajar Haskell Ini adalah langkah yang direkomendasikan untuk belajar Haskell berdasarkan pengalaman membantu orang lain. Daftar rekomendasi bersumber dari salah satu penulis [Haskell Book.](http://haskellbook.com) ## Untuk pembicara non-English - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Jangan memikirkan hal yang tidak langsung anda mengerti*. Lanjutkan terus! ## Komunitas Kanal IRC kami adalah `#haskell-beginners` di Freenode. Situs klien IRC [disini](http://webchat.freenode.net/). Haskell [milis](https://wiki.haskell.org/Mailing_lists). ### Panduan Komunitas Lihat [Panduak Komunitas](coc.md) untuk mengerti etika yang diharapkan ketika berada pada kanal IRC. Anda akan mendapatkan peringatan jika Anda melakukan hasutan yang tidak jelas, namun perlu menjadi perhatian bahwa kanal secara eksklusif untuk siapa yang belajar atau mengajarkan Haskell. # Memasang Haskell ## Gunakan Stack untuk melanjutkan dengan Haskell Dapatkan [Stack](https://haskellstack.org) untuk mendapatkan GHC terpasang dan membuat proyek anda. Jika Anda tidak tau apapun tentang Stack dan ingin sebuah ikhtisar, periksa ini [Video pengajaran Stack komprehensif](https://www.youtube.com/watch?v=sRonIB8ZStw). ## Dan juga, JANGAN PASANG HASKELL PLATFORM Sebagai ganti mengikuti instruksi pada Haskell.org, dapatkan Stack. ### Mengapa bukan platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Bagaimana seharusnya Saya mempelajari Haskell? Yang paling direkomendasikan adalah untuk membaca materi kuliah dan menyelesaikan seluruh latihan/pekerjaan rumah untuk versi Spring 13 dari cis1940 diikuti dengan pelajaran FP. Keduanya ditautkan dibawah. Selain dari itu dapat dikategorikan sebagai opsional dan diberitahukan agar anda mengetahui kemana harus mencarinya. ## Haskell Programming from First Principles [@dmvianna](https://github.com/dmvianna) menginginkan saya untuk memberitahu bahwa dibawah ini adalah rekomendasi sumber yang _gratis_. Jika anda ingin memiliki buku, kami sangat merekomendasikan buku kami [Haskell Book!](http://haskellbook.com). Jika kamu tidak mampu membeli bukunya karena alasan apapun, silahkan hubungi kami dengan surat elektronik menggunakan kontak di [our support page](http://haskellbook.com/support.html). ## Kursus cis1940 Yorgey > *Lakukan ini terlebih dahulu*, ini adalah langkah awal yang kami rekomendasikan untuk dikenalkan kepada > Haskell. Tersedia [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Mata kuliah [Brent Yorgey](https://byorgey.wordpress.com) adalah yang terbaik yang saya temukan sejauh ini. Mata kuliah ini berharga karena tidak hanya membekali anda untuk menulis dasar Haskell namun juga membantu anda untuk mengerti parser combinators. Satu-satunya alasan anda tidak seharusnya mulai dengan cis1940 adalah jika anda bukanlah programmer atau adalah yang tidak berpengalaman. Jika demikian, mulailah dengan [Thompson's book](https://www.haskellcraft.com/craft3e/Home.html) kemudian beralih ke cis1940. --- ## Pelajaran FP > Ini adalah pelajaran yang kami rekomendasikan untuk dikerjakan setelah mata kuliah cis1940 Yorgey. Tersedia di github [disini](https://github.com/bitemyapp/fp-course). Ini akan membantu dan memberikan anda pengalaman secara langsung mengimplementasikan abstraksi yang dikenalkan di cis1940, ini adalah latihan yang _penting_ untuk menjadi nyaman dengan penggunaan Functor/Applicative/Monad/dll sehari-hari pada Haskell. Menempuh cis1940 dan kemudian pelajaran FP mewakili rekomendasi utama dari panduan saya dan bagaimana kami mengajarkan Haskell kepada semua orang. --- ## Pelajaran tambahan setelah pelajaran cis1940 dan FP > Menyediakan materi tambahan untuk topik menengah. cs240h tersedia secara online: - [Spring 14](http://www.scs.stanford.edu/14sp-cs240h/) - [Winter 16](http://www.scs.stanford.edu/16wi-cs240h/) Ini adalah pelajaran online [Bryan O'Sullivan](https://github.com/bos) dari kelas yang ia ajar di Stanford. Jika anda tidak mengetahui siapa ia, coba lihat sebentar pada setengah pustaka setiap aplikasi Haskell yang dibutuhkan dan namanya ada pada pustaka tersebut. Dengan catatan tersendiri bahwa anda telah menyelesaikan pelajaran Yorgey yang ada di modul phantom types, information flow control, language extensions, concurrency, pipes, dan lenses. --- # Sumber untuk topik spesifik pada Haskell Sumber-sumber ini tidak diperiksa atau dicoba kepada pelajar seperti pelajaran cis1940 dan FP, tapi ditautkan pada [the topic listing](specific_topics.md) sehingga anda memiliki gambaran mengenai darimana harus memulai. Hal ini juga termasuk konsep menengah/lanjutan dan subyek seperti alat-alat dan editor teks. ## Dialog > Di pasang pada repositori [disini](dialogues.md). Ini sebenarnya lumayan penting dan membantu. Lihat kesini untuk mengenal lebih dalam pada beberapa variasi topik. ================================================ FILE: guide-it.md ================================================ # La Guida Questa è la strada che raccomando per imparare Haskell. ## Per chi non parla italiano - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### Un consiglio: *non preoccupatevi se non capite qualcosa alla prima lettura*. Andate avanti. ## Comunità Il nostro canale IRC è `#haskell-beginners` su Freenode. Un client web per IRC è disponibile [qui](http://webchat.freenode.net/). La [mailing list](https://wiki.haskell.org/Mailing_lists) di Haskell. ### Linee guida per la comunità [Leggete il post di Chris Done sull'insegnamento](http://chrisdone.com/posts/teaching). Siate gentili e cortesi. Comportamenti crudeli o meschini spaventano gli altri e fanno passare la voglia di partecipare. Crtitiche facili, in cui non mettete impegno, beneficiano soltanto voi e non la persona che le riceve. Non descrivete niente con parole come "facile" o "banale". Chi legge si sentirà stupido perché le cose che definite come triviali possono aver richiesto molto impegno. Spesso chi impara lentamente impara più profondamente, è una cosa che dovremmo perseguire! Non fate finta di essere sorpresi quando qualcuno vi dice che non sa qualcosa. Lo farete sentire soltanto stupido e non avrete ottenuto niente a parte sentirvi più furbi. Non dite beh-in realtà. Come quando qualcuno dice che qualcosa è quasi, ma non completamente corretta, e voi cominciate a dire, "beh, in realtà…" e poi fate una piccola correzione. È molto irritante, specialmente quando la correzione non è pertinente alla conversazione che state avendo. Questo non significa che l'Hacker School non si preoccupi della verità o che non ci interessi essere precisi. Ma questi modi di fare sono quasi sempre più una questione di pavoneggiamento che altro. Non dite agli altri cosa devono fare. Se qualcuno sta completando un esercizio non dovreste interromperlo continuamente con consigli. Lasciate che trovi la sua strada a meno che non lo chieda esplicitamente. Evitare interruzioni è [uno degli obiettivi fondamentali di #haskell-beginners](http://chrisdone.com/posts/teaching). Non lasciate spazio a sottili "ismi". Razzismo, sessismo, omofobia, transfobia, e altri tipi di pregiudizi non saranno tollerati. --- Linee guida tratte dal [manuale della Hacker School ](https://www.hackerschool.com/manual). Grazie per averle rese pubbliche. # Cosa sono Haskell, GHC e Cabal? Haskell è un linguaggio di programmazione, e come potete leggere nei report, la versione più recente è stata rilasciata nel 2010. Il report è disponibile online: [report](http://www.haskell.org/onlinereport/haskell2010/). ## GHC [GHC](http://www.haskell.org/ghc/) è il modo più classico per lavorare in Haskell. Include un compilatore, un REPL (interprete), un gestore automatico di pacchetti e librerie, ed altro. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) è software per gestire i progetti haskell e risolvere le dipendenze. È lo strumento che vi permetterà di installare i pacchetti, tipicamente ciascuno nel proprio sandbox. Cabal è equivalente a Bundler di Ruby, pip di Python, NPM di Node, Maven, etc. GHC gestisce i pacchetti indipendentemente, Cabal sceglie quale versione installare. # Il set-up dei tool ## Ubuntu [Questo PPA](http://launchpad.net/~hvr/+archive/ghc) è ottimo ed è quello che uso su tutte le mie macchine linux, sia per i build automatici che per lo sviluppo. Istruzioni specifiche: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.20 ghc-7.8.3 happy-1.19.4 alex-3.1.3 ``` Aggiungete poi la seguente linea al vostro `$PATH` (bash\_profile, zshrc, bashrc, etc): ``` ~/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.8.3/bin:/opt/happy/1.19.4/bin:/opt/alex/3.1.3/bin ``` *Opzionale:* Potete anche aggiungere `.cabal-sandbox/bin` al vostro path. Il codice che state sviluppando attivamente sarà così disponibile dalla linea di comando. Questo funziona solo quando la directory in cui siete è un sandbox di cabal. ## Debian ### Usando Ubuntu PPA Se non state usando Debian stable, le stesse istruzioni che abbiamo indicato per Ubuntu fuzionano, ma dovrete eseguire un comando in più. Immediatamente dopo che il comando `sudo add-apt-repository -y ppa:hvr/ghc` lanciate: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` Per altre versioni di Debian dovete solo rimpiazzare tutte le occorrenze di `jessie` con il nome della versione che state utilizzando nel comando di cui sopra. Se per qualche ragione il file `/etc/apt/sources.list.d/hvr-ghc-jessie.list` non dovesse esistere, allora `/etc/apt/sources.list` dovrebbe contenere una linea come questa: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Rimpiazzate quindi in quella linea `jessie` con `trusty`. ### Compilazione manuale Potete seguire [questa](http://www.davesquared.net/2014/05/platformless-haskell.html) guida scritta per Mac OS X: Note: - Quando configurate ghc settate il prefisso appropriato - Invece di prendere il binario di `cabal-install`, scaricate il codice sorgente e lanciate lo script `bootstrap.sh`. ## Fedora 21 Per installare Haskell 7.8.4 dal repository non ufficiale (Fedora 22+ lo includerà ufficialmente): ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` Come affermato in [petersen/ghc-7.8.4 copr page](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) questo ghc non può essere installato insieme con il ghc di Fedora/EPEL. ## Arch Linux Per installare Haskell dal repository ufficiale su Arch Linux, lanciate ```bash $ sudo pacman -S cabal-install ghc happy alex haskell-haddock-library ``` ## Gentoo Su Gentoo, potete installare i singoli componenti della Haskell Platform attraverso Portage. Se usate `ACCEPT_KEYWORDS=arch` (invece che `ACCEPT_KEYWORDS=~arch`), Portage installerà versioni più vecchie di Haskell. Tenendone di conto, se usate `ACCEPT_KEYWORDS=arch`, aggiungete le seguenti linee a `/etc/portage/package.accept_keywords`. dev-haskell/cabal-install ~arch dev-lang/ghc ~arch Una volta fatto quello, lanciate: ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo include una versione "stabile" (leggi: vecchia) di `cabal-install` nell'albero di Portage, quindi vorrete usare `cabal-install` per installare la versione più recente. I backslash sono intenzionali. ```bash $ \cabal update # I backslash $ \cabal install cabal-install # sono intentionali ``` Adesso avete installato cabal a livello globale con portage, e localmente nella vostra home directory con `cabal-install`. Il prossimo passo è assicurarsi che quando lanciate `cabal` in un terminale, la vostra shell lanci la versione più recente che è nella vostra home directory. Aggiugete le linee seguenti nel file di configurazione della vostra shell: ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` Se non sapete quale shell avete, è molto probabile che la vostra shell sia Bash. Se usate Bash, il file che dovete editare è `~/.bashrc`. se usate Z-shell, il file è `~/.zshrc`. Potete lanciare il seguete comando per sapere qual'è la vostra shell. ```bash echo $SHELL | xargs basename ``` Io uso zsh, quindi il comando restituisce `zsh` quando lo lancio. Una volta fatto tutto questo, dovrete installare i tool addizionali `alex` e `happy`. ```bash $ cabal install alex happy ``` Congratulazioni! Adesso avete una installazione di Haskell funzionante! ## Mac OS X ### 10.9 Installate [GHC per Mac OS X](http://ghcformacosx.github.io/), che include GHC e Cabal. La guida vi darà istruzioni su come installare GHC e Cabal nel vostro path una volta che avete copiato la .app da qualche parte sul disco fisso. ### 10.6-10.8 Eseguite l'installazione dei binari come scritto qui sotto usando [questo tarball](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2). ## Windows - L' [installer minimo per windows di GHC](http://neilmitchell.blogspot.com/2014/12/beta-testing-windows-minimal-ghc.html) è in grado di compilare `network` e altro. È tecnicamente in beta ma dovrebbe funzionare per gli scopi di chiunque legga questa guida. Non dimenticatevi di lanciare l'installer come amministratore, dato che è richiesto l'accesso alla directory di sistema 'Programmi'. ## Altri utenti Linux Scaricate l'ultima distribuzione binaria di cabal e ghc: - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). # Corsi primari ## Il corso cis1940 di Yorgey > *Seguite questo per primo*, è la strada che raccomando per il primo approccio ad > Haskell. Disponibile [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Il corso di [Brent Yorgey](https://byorgey.wordpress.com) è il migliore che ho trovato finora. Questo corso ha valore non solo perché vi rende in grado di scrivere codice Haskell basilare ma anche perché vi aiuterà a comprendere i parser combinators. L'unica ragione per cui non dovreste cominciare con cis1940 è se non siete programmatori o se non avete molta esperienza. In questo caso, suggerisco di iniziare con il [libro di Thompson](https://www.haskellcraft.com/craft3e/Home.html) e poi passate a cis1940. --- ## Il corso FP > Questo è il corso che raccomando dopo cis1940 di Yorgey Disponibile su github [qui](https://github.com/bitemyapp/fp-course). Questo vi darà esperienza nell'implementare direttamente le astrazioni introdotte in cis1940. Questi esercizi sono *fondamentali* per sviluppare confidenza con gli usi comuni di Functor/Applicative/Monad/etc. in Haskell. La raccomandazione principale di questa guida è seguire cis1940 e poi FP: questo è il percorso che seguo per insegnare Haskell a tutti. --- ## Corso Supplementare cs240h > Fornisce più materiale sugli argomenti intermedi Disponibile [online](http://www.scs.stanford.edu/14sp-cs240h/). Questo è il corso online di [Bryan O'Sullivan](https://github.com/bos) tratto dal corso che insegna a Stanford. Se non sapete chi è, date un'occhiata alla metà delle librerie che qualsiasi progetto Haskell richiede e ci troverete il suo nome. Sa avete già seguito il corso di Yorgey sono particolarmente rilevanti i moduli sui phantom types, il flusso di controllo delle informazioni, le estensioni del linguaggio, le concorrenza, le librerie pipes e lenses. --- ## Materiale di riferimento per i tre corsi [Learn You a Haskell for Great Good (LYAH)](http://learnyouahaskell.com) e [Real World Haskell](http://book.realworldhaskell.org) (Grazie bos!) sono disponibili online. Raccomando RWH come referenza (è un libro spesso). I capitoli sul parsing e sulle monadi sono ottimi per arrivare a capire l'utilità delle monadi stesse. Alcuni hanno detto che è piaciuto molto. Probabilmente è un buon follow-up per imparare gli idiomi in modo pratico, una volta che avete imparato le cose essenziali di Haskell? ### Cosa fa quel syntactic sugar `<-` / `do` / sulle list comprehension? Eccellente [articolo](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html). ### Per capire list e fold - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### Per imparare alcune Typeclass di uso comune Utile per capire `Functor`, `Applicative`, `Monad`, `Monoid` e altre Typeclass di uso comune, ma anche informazioni specifiche di Hask e di Teoria delle Categorie: - La [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Capire i messaggi di errore più comuni di Haskell - [Capire i messaggi di errore più comuni](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Laziness, strictness, guarded recursion - Il [libro](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) di Marlow sul parallelismo e la concorrenza ha una delle migliori introduzioni alla laziness e alla normal form che abbia trovato. Avrete bisogno di materiale in più se non acquisite i concetti subito. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Domanda su Stack Overflow '[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - La presentazione di [Johan Tibell](https://github.com/tibbe) su [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Breve dimostrazione ```haskell let a = 1 : a -- guarded recursion, (:) è lazy su di esso si può usare pattern matching. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- non guarded, (*) è strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Leggete la documentazione e le note sulla implementazione di unsafeDupablePerformIO Commento da un thread di Reddit, di `glaebhoerl` > Nota interessante: GHC deve nascondere la rappresentazione dello state token > dietro un tipo IO astratto perché lo state token deve sempre essere usato linearmente (non > duplicato o droppato), ma il type system non può garantire che questo accada. Clean, un altro > linguaggio lazy come Haskell, ha 'uniqueness types' (sono come i linear types > e possibilmente diversi per aspetti di cui non sono a conoscenza), e espongono > World-passing direttamente e forniscono una monade IO (non astratta) solo per > convenienza. # Monadi and monad transformers > Non cominciate a imparali finché non capite typeclass, Monoid, Functor e > Applicative! Implementate per conto vostro le monadi della libreria standard (List, Maybe, Cont, Error, Reader, Writer, State) per capirle meglio. Poi potreste provare a scrivere un interprete monadico per piccole espressioni facendo riferimento all'articolo [Monad Transformers Step by Step](http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf) (menzionata in 'monad transformers' qui sotto). Scrivere diversi interpreti cambiando solo la monade per cambiare la semantica può aiutarvi a capire in che cosa consiste. Poi reimplementate `Control.Monad`. Funzioni come `mapM` o `sequence` sono buone opportunità per fare esercizio e scrivere codice monadico generico. Il corso FP può essere usato come guida a questo scopo, che include anche lo scrivere la vostra typeclass Applicative. Referenza: - Commenti su Reddit di htmltyp and Crandom [qui](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Commenti su Reddit di jozefg [qui](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Monad transformers - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf) (attenzione il codice riportato è datato). # Testare, test, specifiche, testing generativo e di proprietà - Questo [tutorial](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) di Kazu Yamamoto è fantastico. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Un'ottima libreria per imparare in modo semplice come funziona lo streaming IO in generale; la conoscenza è trasferibile a librerie più complesse come Pipes e Conduit # Parsing in Haskell - [Tutorial](https://github.com/JakeWheat/intro_to_parsing) sui Parser combinator per Haskell, usando Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Parsare e generare JSON Aeson è la soluzione di parsing [JSON](https://json.org) standard in haskell. Disponibile su [hackage](https://hackage.haskell.org/package/aeson) e [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Tutorial di Aeson](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Algoritmi per grafi e strutture dati - Il [pacchetto fgl](https://hackage.haskell.org/package/fgl) gli [algoritmi](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html) puramente funzionali per trovare la strada più breve. - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph source from Containers package](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - Il [pacchetto graphs](https://hackage.haskell.org/package/graphs). - [Domande su SO riguardo a PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS for free](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Ambienti di sviluppo ## Emacs - [Il tutorial di Alejandro Serras](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [I miei dotfiles](https://github.com/bitemyapp/dotfiles/) - [Il config emacs di Chris Done](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Pagina di Vim su haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Lavorare con Cabal ## Linee guida di Cabal Prima dell'introduzione dei sandbox, gli utenti Haskell incappavano nel problema definito Cabal Hell (Inferno di Cabal). Se non utilizzate una sandbox, cabal installerà il pacchetto nel vostro user package-db. Questa *non* è in genere una buona idea, fatta l'eccezione per alcuni pacchetti di base come Cabal, alex e happy. Nient'altro dovrebbe essere installato nel package-db dell'utente né tanto meno a livello globale, a meno che non sappiate cosa state facendo. Alcune raccomandazioni per non cadere nel Cabal Hell sono disponibili [qui](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). Per provare un pacchetto o cominciare un progetto, iniziate lanciando `cabal sandbox init` in una nuova directory. In poche parole: - Quando installate nuovi pacchetti, create nuovi progetti o pre-esistenti, o cominciate esperimenti usate sempre i sandbox. - Usate `cabal repl` invece per iniziare una istanza di ghci come project-scoped Questo approccio basato sui sandbox dovrebbe scamparvi dai problemi relativi alle dipendenze dei paccheti, ma è incompatibile con il modo in cui la Haskell Platform fornisce i pacchetti binari. Se state imparando Haskell e non capite come funzionano ghc-pkg e Cabal, *evitate la haskell platform*, ed usate invece le istruzioni all'inizio della guida. ## Stackage Tutti gli utenti (di solito utenti di Yesod) che hanno problemi di build potrebbero provare ad utilizzare Stackage. - Un buon riassunto di Stackage è [qui](https://www.fpcomplete.com/blog/2014/05/stackage-server). Secondo l'opinione dell'autore, Stackage è in genere più utile di `cabal freeze`. # Hoogle e Haddock ## Ricerca di codice mediante type signature Il [motore di ricerca Hoogle](http://www.haskell.org/hoogle/) può cercare per tipo. Per esempio, guardate i risultati della ricerca per `(a -> b) -> [a] -> [b]` [qui](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Lo trovate anche su fpcomplete [qui](https://www.fpcomplete.com/hoogle). Anche [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (che cerca su tutto Hackage per default). ## Setup della tua istanza locale di Hoogle Guardate [qui](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Aggiusta la tua documentazione hackage](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Documentazione Hackage v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Fate attenzione, questi post sono *lievemente obsoleti*: per esempio, adesso Hackage vanta nuovi modi di mostrare informazioni, documentazione e stato del build. ## Quello che davvero avete bisogno di sapere Per far includere ad haddocks la documentazione per i pacchetti correlati, dovete settare `documentation: True` nel vostro `~/.cabal/config`. Se lasciato sul valore di default (`False`) o settato a `False`, prima di rigenerare la documentazione dovrete rimuovere tutti i vostri pacchetti e reinstallarli. L'altra cosa da tenere a mente è che a causa del modo in cui il parametro `$pkg` viene interpretato *da* cabal, non da voi, i parametri `html-location` e `content-location` *devono essere fra apici* e inseriti in una shell o in uno shell script. Non funzioneranno in un Makefile, perché crederanno di essere variabili di Make! ```bash #! /usr/bin/env sh # potete scrivero su una linea sola non mettendo backslash cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Se siete fan di [TravisCI](https://travis-ci.org) come lo sono io, allora vi consiglio *caldamente* di dare un'occhiata a [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) come base per il `travis.yml` dei vostri progetti Haskell. # Frontend/JavaScript Abbiamo l'imbarazzo della scelta! Ci sono tre scelte principali che raccomanderei: * [Haste](http://haste-lang.org/) un compilatore da Haskell a JavaScript - Il [compilatore](https://github.com/valderman/haste-compiler) su github. - Una [demo](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) eccellente di Haste con un progetto di esempio. * [GHCJS](https://github.com/ghcjs/ghcjs) - [Introduzione a GHCJS](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Non è strettamente Haskell come Haste e GHCJS, ma è una scelta popolare fra i programmatori Haskell - Scritto in ed ispirato ad Haskell - Provate purescript nel vostro browser [here](http://try.purescript.org/) - Ottima guida per [cominciare a usarlo](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## Quale linguaggio scegliere per il frontend? GHCJS e Haste sono entrambi interamente compatibili con Haskell. GHCJS è compatibile con un numero maggiore di pacchetti Haskell rispetto a Haste, ma questo non è rilevante per molti progetti frontend. Al contrario, PureScript non è Haskell, per tanto non potrete condividere il codice fra frontend e backend. GHCJS ha un runtime più grande, a 100kb (luite ci sta lavorando). Haste e PureScript sono competitivi. PureScript ha la migliore integrazione con i tool di JS (usa gulp/grunt/bower), mentre GHCJS e Haste si integrano meglio con i tool di Haskell (Cabal). Tutti e tre sono un'ottima scelta e possono funzionare per la maggioranza dei progetti frontend. # Per una comprensione più profonda della laziness, NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## Articoli di ricerca sul lazy lambda calculi - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtlm) # Parallelismo/Concorrenza - Il libro [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929) di Simon Marlow è probabilmente il migliore che abbia mai letto sull'argomento. - Un [walk-through](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) completo su testing e incremental development di un applicazione multi-threaded in Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses e Prisms Una volta che vi trovate a vostro agio con Haskell, è molto utile imparare Lens e Prism, anche se solo come "utente". Non avete bisogno di capire le categorie sottostanti perchè vi siano utili. La difficoltà di usare la libreria Lens è generalmente sovrastimata. Chiunque sia a suo agio con Functor/Foldable/Traversable (o anche solo il primo) può usare lens e prism per rendersi la vita più facile. Se vi è capitato di fare qualcosa come: `(fmap . fmap)` stavate usando mentalmente le 'lenti'. Raccomando questi due tutorial/introduzioni: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Leggete questo per maggiori informazioni: [pacchetto Lens su hackage](http://hackage.haskell.org/package/lens). # Schemi di ricorsione Alcune delle pazze parole di cui avete sentito parlare che finiscono con \*-morfismo riguardano la ricorsione. NB - prima di iniziare a studiare il materiale che segue dovreste sapere come implementare foldr per le liste e almeno un'altra struttura di dati, tipo un albero. (i fold sono catamorfismi) Sapere come implementare un unfold (anamorfismo) per le stesse strutture dati è complementare. Questo materiale si compenetra con traversable e foldable. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Buona dimostrazione su come l'ilomorfismo sia la composizione di cata e ana. - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - Questa guida è ottima. - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core e ottimizzazione della performance - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Tipi e Teoria delle Categorie > *Non* è necessaria per scrivere Haskell, solo per quelli interessati! Se volete imparare di più su tipi e teoria delle categorie: - [La guida di Catster](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) e [La seconda guida Catster](http://byorgey.wordpress.com/catsters-guide-2/) - Il [wikibook haskell](http://en.wikibooks.org/wiki/Haskell/Category_theory) ha dei bei diagrammi - [Teoria delle categorie](http://www.haskell.org/haskellwiki/Category_theory) su haskellwiki, ha anche buoni link ad altre risorse - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), include alcuni esempi pratici. - La lista [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) di Pierce. ## Libri - [Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) le raccomandazioni di Kmett - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) e [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). I libri di testo standard sulla teoria delle categorie - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) è la miglior introduzione alla teoria delle categorie focalizzata sui linguaggi di programmazione. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Altri argomenti divertenti ## Parametricità, ad-hoc vs. polimorfismo parametrico e teoremi liberi - [Parametricity](tony_parametricity.pdf). - [Sorgenti TeX](https://github.com/tonymorris/parametricity/) per la presentazione di cui sopra. - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Inizial e Final, DSL, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) meno rilevante nello specifico ma comunque interessante. ## Comonadi - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, una sequenza di tre articoli di Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (computazione) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Tipi dipendenti - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) strizzate gli occhi. - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # Linkare binari staticamente - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Dialoghi > Disponibile in questo repository [qui](dialogues.md). Questi sono in realtà importanti e utili. Leggeteli per approfondimenti su una varietà di argomenti. ================================================ FILE: guide-ja.md ================================================ # Haskellを学ぶ これは、私が教えた経験に基づくHaskellの学習パスであり、[Haskell Book](https://haskellbook.com)の著者の一人が推奨するものです。 #### _すぐに理解できないことを気にする必要はありません_. 前に進みましょう! ## コミュニティ 私たちの IRC チャンネルは `#haskell-beginners` で、[Libera Chat](https://libera.chat/)にあります。 IRCウェブクライアントは[ここ](https://web.libera.chat/)にあります。 Haskellのメーリングリストは[ここ](https://wiki.haskell.org/Mailing_lists)です。 ### コミュニティ・ガイドライン IRCチャンネルで求められる行為については、[コミュニティ・ガイドライン](coc.md)を参照してください。荒らしかどうか判然としない場合は警告処分となりますが、このチャンネルは Haskell を学習したり教えたりする人たちだけのものであることに注意してください。 # Haskell のインストール ## Haskell を始めるには Stack を使う GHC をインストールし、プロジェクトをビルドするためには [Stack](https://haskellstack.org) が必要です。 Stackの概要については、[Stackビデオチュートリアル](https://www.youtube.com/watch?v=sRonIB8ZStw)をチェックしてください。 ## **Haskell Platform をインストールしないでください** Haskell.orgの指示には従わず、Stackを入手してください。 ### なぜ? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Haskell をどのように学ぶべきですか? 13年春学期の cis1940 の講義・演習・宿題を修了した後に関数型プログラミングコースを受講することをお勧めします。どちらも下にリンクがあります。他は選択コースです。 ## Haskell プログラミングの基礎 [@dmvianna](https://github.com/dmvianna) は、以下のリソースはあくまで無料の推奨リソースであると言っています。 もし本を入手できるなら、[Haskell Book](https://haskellbook.com) を入手することを心からお勧めします。もし入手できないなら、 [サポートページ](https://haskellbook.com/support.html) から私たちにメールを送ってください。 ### Haskell Book は、ここで推奨されている主要なリソースをすべて含んでいます。 ## Yorgey の cis1940 コース > Haskell Book を入手していないなら、まずこれを受講してください。 [オンライン](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html)でアクセスできます。 [Brent Yorgey](https://byorgey.wordpress.com) のコースは、私がこれまで見つけた中で最も優れています。 このコースは、基本的な Haskell を書くだけではなく、パーサコンビネータを理解するのにも役立ちます。 あなたがプログラマーでないかまたは経験の浅い場合にはcis1940を始めるべきではありません。 そのような場合は、[Thompson's book](https://www.haskellcraft.com/craft3e/Home.html) から始めて、cis1940に移行してください。 --- ## 関数型プログラミングコース > Yorgeyのcis1940コースの後に受講するべきコースです。 GitHub上のレポジトリ[bitemyapp/fp-course](https://github.com/bitemyapp/fp-course)で公開されています。 このコースでは、cis1940で紹介された抽象化を直接実装します。これは、関手やアプリカティブ、モナドなどの使い方に慣れるために重要です。 cis1940と関数型プログラミングコースはこのガイドの核であり、すべての人にHaskellを教える方法なのです。 --- ## cis1940と関数型プログラミングコースの補足コース > 中級者向けのトピックをより多く提供します。 cs240h はオンラインで利用可能です。 - [14年春学期](http://www.scs.stanford.edu/14sp-cs240h/) - [16年冬学期](http://www.scs.stanford.edu/16wi-cs240h/) [Bryan O'Sullivan](https://github.com/bos)がスタンフォード大学で教えているクラスのオンラインコースです。 彼の名前は、Haskellアプリケーションが必要とするライブラリの約半数に載っています。特に Yorgey のコースを既に受講しているなら、ファントムタイプ、情報フロー制御、言語拡張、並行処理、パイプ、レンズ、パイプ、レンズなどのモジュールに特に注目すべきです。 --- # Haskellの特定のトピックのためのリソース > [トピックリスト](specific_topic.md) これらのリソースは、 中級・上級のコンセプトや、ツールやテキストエディタなどのテーマを含みます。ただし、cis1940や関数型プログラミングコースのように学習者によって十分に精査されたものではありません。 ## 議論 > [議論](dialogues.md) これらは様々なトピックを深く掘り下げており、とても重要です。 ================================================ FILE: guide-ko.md ================================================ # 하스켈 학습 가이드 이 글은 여러분이 하스켈을 배우는데 도움이 될 수 있도록 경험을 바탕으로 만들어진 가이드로 [하스켈 북 (Haskell Book)](https://haskellbook.com)의 저자 중 한 사람의 추천 목록입니다. ## 비 영어권 사람들을 위한 번역 - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### _이해가 잘 안된다고 계속 붙잡고 있지 마세요_. 진도를 계속 나가세요! ## 커뮤니티 저희 IRC 체널은 Freenode의 `#haskell-beginners` 입니다. IRC 웹 클라이언트 [here](http://webchat.freenode.net/). 하스켈 [메일링 리스트](https://wiki.haskell.org/Mailing_lists). ### 커뮤니티 규칙 IRC 체널의 [커뮤니티 규칙](cdc.md)을 꼭 읽어주세요. 여러분이 지나치게 트롤링을 하지 않는 한 경고로 끝나겠지만, 반드시 이 체널은 하스켈을 배우고 가르치는 공간이라는 점을 명심해주세요. # 하스켈 설치하기 ## 하스켈을 설치하기 위해 Stack을 사용하세요 GHC를 설치하고 프로젝트를 만들기 위해 [Stack](https://haskellstack.org)을 사용하세요. Stack을 처음 들어보거나 개요를 보기 원하신다면, [comprehensive Stack video tutorial](https://www.youtube.com/watch?v=sRonIB8ZStw)을 참고하세요. ## 그리고 HASKELL PLATFORM으로 설치하지 마세요 Haskell.org에서 지시하는 대로 설치하지 마시고, Stack을 사용하세요. ### 왜 platform을 사용하면 안되나요? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # 하스켈을 어떻게 배워야 하나요? 저희들은 2013년 봄학기 cis1940 강의에 있는 모든 문제를 풀어본 다음에 FP강의를 듣는 방법을 추천합니다. 두 강의 모두 아래에 링크가 걸려있습니다. 그 외에는 선택이며, 여러분이 찾을 수 있도록 아래에 링크가 있습니다. ## Haskell Programming from First Principles. [@dmvianna](https://github.com/dmvianna)는 아래의 내용이 무료 권장 자료 일 뿐이라는 사실을 알려 드리고자합니다. 하지만 만약 책으로 보고 싶다면, 제가 쓴 [Haskell Book!](https://haskellbook.com)을 진심으로 추천합니다. 만약 어떤 이유로든 책을 구입할 여유가 없으면 [our support page](https://haskellbook.com/support.html)로 연락해주세요. ### Haskell Book은 여기에서 권장되는 모든 주요 내용을 포함합니다. ## Yorgey의 cis1940 강의 > Haskell Book을 구매하지 않았다면 이 강의를 먼저 들으세요. Haskell 입문을 위한 최고의 수업입니다. [온라인](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html)에서 보실 수 있습니다. [Brent Yorgey](https://byorgey.wordpress.com)의 강의는 제가 찾아 본 것중 가장 좋은 강의입니다. 이 강의는 기본적인 하스켈 코딩능력을 갖춰줄 뿐만이 아니라 parser combinator를 이해하는데 도움을 주기 때문에 중요합니다. 만약 여러분이 프로그래머가 아니거나 프로그래밍을 해본적이 없다면 이 강의로 시작하는 것을 추천하지 않습니다. 그렇다면, [Thompson의 책](https://www.haskellcraft.com/craft3e/Home.html)을 먼저 보고 cis1940로 돌아가세요. --- ## 함수형 프로그래밍 강의 > 이 강의는 Yorgey의 cis1940 강의를 모두 보신 후에 추천드리는 강의입니다. [GitHub](https://github.com/bitemyapp/fp-course)에서 볼 수 있습니다. 이 강의는 cis1940에서 소개한 추상화기법을 직접 사용해보고 실력을 길러줍니다. 이 강의는 하스켈에서 Functor, Applicative, Monad처럼 매일 사용되는 개념들에 익숙해지도록 훈련해주는 중요한 강의입니다. cis1940를 먼저 보고 FP강의를 보는 방법이 저희들이 추천하는 하스켈 학습방법입니다. --- ## cis1940와 FP강의를 본 후의 보충강의 > 더 많은 자료와 중급 주제를 제공합니다. cs240h는 온라인에서 볼 수 있습니다. - [14년 봄학기](http://www.scs.stanford.edu/14sp-cs240h/) - [16년 겨울학기](http://www.scs.stanford.edu/16wi-cs240h/) 이 강의는 Stanford에서 강의하시는 [Bryan O'Sullivan](https://github.com/bos)의 온라인 강의입니다. 만약 이분을 모르신다면, 나중에 필요하게 될 하스켈 라이브러리들을 살펴보면 그의 이름을 발견할 수 있습니다. cis1940를 끝마쳤다면 phantom types나 information flow control, language extensions, concurrency, pipes, lenses 내용은 보신적이 있을 겁니다. --- # Haskell의 특정 주제에 대한 자료 이 자료들은 cis1940와 FP강의를 들은 사람들에 대해 점검해보지 않았지만, 여러분이 어디서 시작해야 할지 도와주기 위해 [주제 리스트](specific_topucs.md)에 링크를 모아두었습니다. 이 리스트에는 툴과 에디터 같은 중급이나 고급정도의 개념들과 주제도 담겨있습니다. ## 토론 > [이 저장소](dialogues.md)에 있습니다. 이것들은 꽤 중요하고 도움이 될겁니다. 여기에 들어가서 다양한 주제들을 만나보실 수 있습니다. ================================================ FILE: guide-pt.md ================================================ # O Guia Este é o caminho que recomendo para se aprender Haskell. #### Uma coisa para se lembrar sempre: *não se preocupe com aquilo que não entender imediatamente*. Apenas continue. ## Comunidade Nosso canal no IRC é `#haskell-beginners` no Freenode. Cliente web para IRC [aqui](http://webchat.freenode.net/). [Listas de e-mails](https://wiki.haskell.org/Mailing_lists) relacionadas a Haskell. ## Diretrizes para a Comunidade [Leia a postagem de Chris Done sobre ensino](http://chrisdone.com/posts/teaching) (Em inglês) Seja gentil e cortês. Ser cruel ou rude assusta as pessoas e as desencoraja a participar. Criticismo barato beneficia apenas a pessoa que o emite, não a pessoa que o recebe. Não descreva coisas como "fáceis" ou "triviais". Você fará pessoas se sentirem mal por terem que trabalhar duro para progredirem. Pessoas que aprendem lentamente frequentemente são aquelas que aprendem melhor, isso é algo para ser celebrado! Sem surpresa fingida. Não se faça de surpreso quando alguém diz que não sabe alguma coisa. Essa pessoa se sentirá mal e você terá conseguido nada além de se sentir afiado. Sem "bom, na verdade". Quando alguém diz algo que está quase - mas não totalmente - correto, e você diz, "bom, na verdade..." e então faz uma correção pequena. Isso é especialmente incômodo quando a correção não tem relação com o assunto conversado. Isso não significa que o Recurse Center não é sobre a busca de verdade ou que nós não nos importamos em ser precisos. Quase todos esses "bom, na verdade" são com intenção de se aparecer, não em benefício da verdade. Sem essa de dirigir no banco de trás. Se você vê as pessoas trabalhando em um problema, você não deveria lançar conselhos intermitentemente. Deixe-as trabalhar a menos que alguém peça por ajuda. Evitar interrupções é [um dos propósitos fundamentais do #haskell-beginners](http://chrisdone.com/posts/teaching) Sem "-ismos" sutis. Racismo, sexismo, homofobia, transfobia, e outros tipos de preconceito não são bem vindos e não serão tolerados. --- Diretrizes do [manual do Recurse Center](https://www.recurse.com/manual). Obrigado por disponibilizar isso, Recurse Center. # Instalando Haskell ## Use a ferramenta Stack para começar com Haskell Instale [Stack](https://haskellstack.org) para ter o GHC (Glasgow Haskell Compiler) instalado e para poder compilar seus projetos. Se você não sabe nada sobre Stack e gostaria de uma visão geral, confira o [tutorial em video sobre Stack](https://www.youtube.com/watch?v=sRonIB8ZStw). ## NÃO INSTALE "HASKELL PLATFORM" Ao invés de utilizar as instruções disponível em Haskell.org, instale Stack. ### Por quê não utilizar "Haskell Platform"? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Como devo aprender Haskell? A principal recomendação é ler as aulas e fazer todos os exercícios/trabalhos de casa do curso cis1940 da Primavera de 2013 seguido pelo curso FP. Links para ambos podem ser encontrados abaixo. Tudo o resto pode ser considerado opcional e é referido aqui para saber onde procurar. ## Alternativamente... [@dmvianna](https://github.com/dmvianna) quer que saibam que estes são apenas os recursos _grátis_ recomendados. Se estiver disposto a adquirir um livro, recomendamos o [nosso livro](https://haskellbook.com). Este livro substitui todos os recursos primários aqui disponíveis. ## Curso cis1940 do Yorgey > *Faça este primeiro*, esta é a minha recomendação de como ser introduzido > ao Haskell. Disponível [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). O curso de [Brent Yorgey](https://byorgey.wordpress.com) é o melhor que eu encontrei até agora. Esse curso é importante porque ele não só vai equipá-lo a escrever Haskell básico mas também vai ajudá-lo a entender *parser combinators*. A única razão pela qual você não deveria começar com o cis1940 é se você não for um programador ou se for um que é inexperiente. Se esse é o caso, comece com o [livro do Thompson](https://www.haskellcraft.com/craft3e/Home.html) e depois o cis1940. --- ## Curso FP > Este é o curso que recomendo fazer após o curso cis1940 do Yorgey. Disponível no github [aqui](https://github.com/bitemyapp/fp-course). Isso vai reforçar e lhe dar experiência implementado diretamente as abstrações introduzidas no cis1940. Essa prática é *crítica* para alguém se tornar confortável com o uso diário de *Functors*/*Applicatives*/*Monads*/etc em Haskell. Fazer o cis1940 e então o curso do FP representa a recomendação fundamental do meu guia, e é como eu ensino Haskell para todo mundo. --- ## Curso suplementar cs240h > Fornece mais materiais em tópicos intermediários Disponível [online](http://www.scs.stanford.edu/14sp-cs240h/). Essa é a versão online do curso que o [Bryan O'Sullivan](https://github.com/bos) leciona em Stanford. Se você não sabe quem ele é, dê uma olhada em metade das bibliotecas que qualquer aplicação em Haskell acaba precisando e o nome dele estará nela. Se você já fez o curso do Yorgey, são particularmente interessantes os módulos sobre tipos fantasma (*phantom types*), controle de fluxo da informação (*information flow control*), extensões de linguagem (*language extensions*), concorrência, *pipes* e *lenses*. --- ## Material de referência para os três cursos [Learn You a Haskell for Great Good (LYAH)](http://learnyouahaskell.com) e o [Real World Haskell](http://book.realworldhaskell.org) (Obrigado, bos!) estão disponíveis online. Eu recomendo o RWH como referência (livro grosso). Os capítulos sobre *parsing* e *monads* são ótimos para entender onde *monads* são úteis. Outras pessoas já disseram que gostaram muito deles. Talvez seja um bom seguimento para aplicações práticas depois que você já está acostumado com o essencial de Haskell. ### O que os açúcares sintáticos `<-` / `do` / compreensão de listas fazem exatamente? Excelente [artigo](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html). ### Para entender listas e *folds* - [Explique *folds* em Listas para si mesmo](http://vimeo.com/64673035) ### Para aprender *typeclasses* comuns Útil para entender `Functor`, `Applicative`, `Monad`, `Monoid` e outras *typeclasses* em geral, mas também conceitos de Teoria das Categorias específicos à Hask. - A [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Entendendo mensagens de erro básicas do Haskell - [Entendendo mensagens de erro básicas](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) ### Avaliação preguiçosa, estrita, recursão guardada - O [livro](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) de Marlow paralelismo e concorrência tem uma das melhores introduções sobre avaliação preguiçosa e forma normal que já encontrei. Use outros materiais também se não fizer sentido imediatamente. - [Mais pontos para a avaliação preguiçosa](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh minha preguiça!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Questão no SO '[Haskell tem otimização de recursão de cauda?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - Slides do [Johan Tibell](https://github.com/tibbe) de uma palestra sobre [raciocinando sobre avaliação preguiçosa](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Breve demonstração ```haskell let a = 1 : a -- recursão guardada, (:) é preguiçoso let (v : _) = a -- e é possível fazer *pattern matching* > v 1 > head a -- head a == v 1 let a = 1 * a -- recursão não guardada, (*) é estrito > a *** Exception: <> ``` # IO - [Ordem de avaliação e símbolos de Estado](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Revelando o mistério da IO *monad*](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - ["Afirmações" de primeira classe](http://blog.jle.im/entry/first-class-statements). - [Haddocks para System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Leia a documentação e nota de implementação da função `unsagedupableperformio` Comentário de *thread* no Reddit por `glaebhoerl` > Nota importante: o GHC precisa esconder a representação do símbolo de > estado atrás de um tipo abstrato de IO porque o símbolo de estado sempre > deve ser usado linearmente (não duplicado ou abandonado), mas o sistema de > não pode reforçar isso. Clean, uma outra linguagem preguiçosa semelhante a > Haskell, tem tipos de unicidade (que são como tipos lineares e possivelmente > diferente em maneiras das quais não estou informado), e eles expõe a "passagem > do Mundo" diretamente e fornece a *monad* (não abstrata) apenas por conveniência. # *monads* e transformadores de *monad* (*monad transformers*) > Não faça esses até que você entenda *typeclasses*, *Monoid*, *Functor* e *Applicative*! Implemente as *monads* da biblioteca padrão ( *List*, *Maybe*, *Cont*, *Error*, *Reader*, *Writer*, *State* ) por si mesmo para entendê-las melhor. Então talvez escreva um interpretador monádico para uma pequena linguagem de expressões usando o artigo [Passo-a-passo em *Monad Transformers*](http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf) (mencionado abaixo em 'monad transformers'). Escrever vários interpretadores apenas mudando a *monad* para mudar a semântica pode ajudar a entender o que está acontecendo. Além disso, reimplemente `Control.Monad`. Funções como `mapM` ou `sequence` são boas oportunidades para praticar escrevendo código monádico genérico. O curso FP pode ser usado como um guia para esse processo, o que também vai envolver escrever seu próprio *Applicative*. Créditos: - comentário no Reddit feito por htmltyp e Crandom [aqui](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - comentário no Reddit feito por jozefg [aqui](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Monad Transformers - [Uma introdução gentil a *Monad Transformers*](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [passo-a-passo em *Monad transformers*] (http://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf) (Aviso! Código desatualizado). # Testando, testes, especificações, teste de propriedades/generativo - Este [tutorial](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) por Kazu Yamamoto é fantástico. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Biblioteca simples e boa para aprender como funciona *streaming IO* em geral, conhecimento transferível para bibliotecas como Pipes e Conduit. # *Parsing* em Haskell - [Tutorial](https://github.com/JakeWheat/intro_to_parsing) em *parser combinators* para Haskell usando a Parsec - [Escrevendo a sua própria micro-parsec](http://olenhad.me/articles/monadic-parsers/) ## *Parsing* e geração de JSON Aeson é a solução padrão para *parsing* de [JSON](https://json.org) em Haskell. Disponível no [hackage](https://hackage.haskell.org/package/aeson) e [github](https://github.com/bos/aeson). - [Fazendo *parsing* de JSON usando a Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson tipos criados pelo usuário](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Fazendo o *parsing* de dados não-determinísticos com a aeson tipos de soma](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Tutorial Aeson](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Algoritmos de Grafo e Estrutura de Dados - O [pacote fgl](https://hackage.haskell.org/package/fgl) particularmente o caminho mais curto puramente funcional, o [algos](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Grafos Indutivos e Algoritmos de Grafos Funcionais](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - Uma Biblioteca de Grafos Funcional](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Código fonte da Data.Graph do pacote Containers](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - O [pacote graphs](https://hackage.haskell.org/package/graphs). - [Pergunta no SO sobre PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS de brinde](https://www.fpcomplete.com/user/edwardk/phoas). - [Amarrando o nó](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Ambiente de Desenvolvimento ## Emacs - [Tutorial de Alejandro Serras](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [Meus *dotfiles*](https://github.com/bitemyapp/dotfiles/) - [Configuração do emacs do Chris Done](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Página do Vim no haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [Plugin do vim para o GHC-Mod](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Trabalhando com Cabal ## Diretrizes do Cabal O *Cabal Hell* (Inferno do Cabal) era um problema para usuário de Haskell antes da introdução das *sandboxes*. Instalar fora de uma *sandbox* vai instalar no package-db de seu usuário. Isso *não* é uma boa ideia, exceto para pacotes fundamentais como Cabal, alex e happy. Nada além disso deve ser instalado nos package-dbs do usuário ou global a menos que você saiba o que está fazendo. Algumas melhores práticas para evitar o *cabal hell* estão disponíveis [aqui](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). Para experimentar um pacote ou iniciar um projeto, comece fazendo `cabal sandbox init` num novo diretório. Colocando brevemente: - Sempre use *sandboxes* para instalar novos pacotes, compilar projetos novos ou existentes, ou iniciar experimentos. - Use o `cabal repl` para iniciar uma instância do ghci com escopo limitado ao projeto. A abordagem baseada em *sandbox* que sugiro deve evitar problemas em dependência de pactes, mas é incompatível com a maneira que a Plataforma Haskell fornece pacotes pré-compilados. Se você ainda está aprendendo Haskell e não entende como o ghc-pkg e o Cabal funcionam, *evite a plataforma* e em vez dela use as instruções para instalação no começo deste guia. ## Stackage Para qualquer usuários (principalmente os do Yesod) que tem problemas de compilação, considere o Stackage. - Um bom sumário do Stackage [aqui](https://www.fpcomplete.com/blog/2014/05/stackage-server). Na opinião do autor, o Stackage é geralmente mais útil do que o `cabal freeze`. # Hoogle e Haddock ## Pesquise código pela *type signature* O [motor de buscas Hoogle](http://www.haskell.org/hoogle/) pode pesquisar pelos tipos. Por exemplo, olhe os resultados de busca para `(a -> b) -> [a] -> [b]` [aqui](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Também hospedado pelo fpcomplete [aqui](https://www.fpcomplete.com/hoogle). Também o [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (que por padrão tem tudo do hackage disponível para pesquisa). ## Configurando sua própria instância local do Hoogle Dê uma olhada [aqui](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Conserte sua documentação do hackage](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Documentação v2 do Hackage](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Perceba que essas postagens estão *levemente desatualizadas*: por exemplo, agora o Hackage exibe informação nova com destaque com informação de documentação e o estado da *build*. ## O que você realmente precisa saber Para fazer com que o haddocks inclua documentação para pacotes relacionados, você deve setar `documentation: True` no seu `~/.cabal/config`. Se ele for deixado no padrão (`False`) ou setado para `False`, você vai precisar deletar todos os seus pacotes e reinstalar antes de gerar os haddocks. Outra coisa para se ter em mente é que devido ao modo como o parâmetro `$pkg` é interpolado *pelo* cabal, não por você, os parâmetros `html-location` e `content-location` *precisam estar em aspas simples* e configurados num *shell* ou contidos num *shell script*. Eles não vão funcionar num Makefile, porque ele vai pensar que são variáveis para o Make! ```bash #! /usr/bin/env sh # You can write it one one line by skipping the backslashes cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Se você é um grande fã do [TravisCI](https://travis-ci.org) como eu sou, então recomendo *fortemente* que considere o [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) como base para o `travis.yml` em seus projetos em Haskell. # *Frontend*/Javascript Nós temos muita coisa nessa área! Existem três opções principais que eu recomendaria: * [Haste](http://haste-lang.org/) um compilador de Haskell para Javascript - O [compilador](https://github.com/valderman/haste-compiler) no github. - Uma excelente [demonstração](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) do Haste com um projeto de exemplo * [GHCJS](https://github.com/ghcjs/ghcjs) - [Introdução ao GHCJS](http://weblog.luite.com/wordpress/?p=14) - [Interfaces Web Funcionais e Reativas com GHCJS e Sodium](http://weblog.luite.com/wordpress/?p=127) - [Escrevendo plugins para o Atom em Haskell usando ghcjs](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Não é estritamente Haskell como o Haste e o GHCJS, mas é uma escolha popular entre os Haskellers - Escrito em e inspirado pelo Haskell - Experimente o purescript em seu navegador [aqui](http://try.purescript.org/) - Ótimo guia para [começar](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## Qual linguagem *frontend* eu deveria usar? GHCJS e Haste são ambos totalmente Haskell. O GHCJS vai funcionar com mais pacotes Haskell do que o Haste, mas isso não influencia muitos projetos de *frontend*. Purescript sequer é Haskell, então compartilhamento direto de código com seu backend não vai funcionar. O custo em tempo de execução do GHC é o mais caro próximo dos 10KB (luite está trabalhando nisso). O Haste e o PureScript são competitivos. O PureScript tem a melhor integração com as ferramentas JavaScript (ele usa gulp/grunt/bower), o GHCJS e o Haste se integram melhor com as ferramentas Haskell (Cabal). Todos os três são ótimas escolhas e vão funcionar bem para a maior parte dos projetos de *frontend*. # Para um entendimento mais completo sobre avaliação preguiçosa, NF, WHNF - [Notas sobre cálculo lambda](https://vec.io/posts/notes-on-lambda-calculus). ## Artigos de pesquisa sobre cálculo lambda preguiçoso - [Um cálculo lambda com chamada por necessidade](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrando Redução em Cálculo Lambda](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [O cálculo lambda preguiçoso](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Avaliação preguiçosa em Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Paralelismo/Concorrência - [Programação Paralela e Concorrente em Haskell](http://chimera.labs.oreilly.com/books/1230000000929). Este livro de Simon Marlow é provavelmente o melhor que já li no tema de Paralelismo e Concorrência. - Um bom [passeio](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) através do processo de teste e desenvolvimento incremental de uma aplicação multi-*thread* em Haskell. - [Programação Funcional Reativa](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # *Lenses* e *Prisms* Depois de estar confortável em Haskell, considere seriamente aprender *Lenses* e *Prisms*, mesmo que somente como "usuário". Você não precisa aprender a teoria das categorias utilizada para que eles sejam úteis. Muitos superestimam demais a dificuldade em se usar Lens. Qualquer um confortável com *Functor*/*Foldable*/*Traversable* (ou até mesmo só com o primeiro) pode usar *lenses* e *prisms* para tornar sua vida mais feliz. Se você já fez algo como: `(fmap . fmap)` você está utilizando *lenses* na sua cabeça. Eu recomendo estes dois tutoriais/introduções: - [Um pequeno tutorial iniciante em lens](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: *Lenses*, *Folds* e *Traversals*](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Olhe aqui para mais informações: [Pacote Lens no hackage](http://hackage.haskell.org/package/lens). # Esquemas de Recursão Algumas das palavras \*-morfismo que você já ouviu tratam na verdade de recursão. Nota - antes de se aventurar neste material, você deveria saber como implementar o `foldr` para listas e para pelo menos mais uma estrutura de dados, como uma árvore. (*folds* são catamorfismos) Saber como se implementa um `unfold` (anamorfismo) para a mesma estrutura vai facilitar um pouco as coisas. Este material se encaixa com *traversable* e *foldable*. - [Uma introdução a esquemas de recursão](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Não tema o *cat*](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) (NT - em inglês existe um trocadilho com o prefixo de catamorfismo - cat - e o termo cat (gato)) Boa demonstração de como hilomorfismo é a composição de catamorfismo e de anamorfismo. - [Esquemas de Recursão](http://comonad.com/reader/2009/recursion-schemes/) - Este guia é excelente. - [Programação Funcional com bananas, *lenses*, envelopes e arame farpado(http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorfismos](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core e tunando a performance - [Escreva Haskell tão rápido quanto C](write_haskell_as_fast_as_c.md) - [Wiki do GHC: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [Questão no SO: Lendo o GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell tão rápido quanto C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Capítulo 25: Perfilação e Otimização](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Teorias dos Tipos e das Categorias > *Não é* necessário saber isso para programar em Haskell, é apenas para quem se interessar! Se você quiser um material complementar em teoria dos tipos e das categorias: - [Guia do Catster](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) e [Guia do Catster - 2](http://byorgey.wordpress.com/catsters-guide-2/) - O [wikibook haskell](http://en.wikibooks.org/wiki/Haskell/Category_theory) tem bons diagramas - [Teoria das Categorias](http://www.haskell.org/haskellwiki/Category_theory) no haskellwiki, também tem bons links para outros materiais - [Categorias do zero](http://science.raphael.poss.name/categories-from-scratch.html), inclui alguns exemplos práticos. - Lista de [Grandes Trabalhos em LP](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) do Pierce. ## Livros - [Questão no Quora: Qual o melhor livro-texto para teoria das Categorias?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) Recomendações do Kmett - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) e [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Os livros-texto padrão sobre o tema. - [Fundamentos Práticos para Linguagens de Programação, do Harper](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) é a melhor introdução à teoria dos tipos que já li. - [Teoria dos tipos e Programação Funcional](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Outros tópicos divertidos ## Parametricidade, polimorfismo ad-hoc vs. paramétrico, teoremas livres - [Parametricidade](tony_parametricity.pdf). - [Fontes em TeX](https://github.com/tonymorris/parametricity/) para o texto acima. - [Tornando o polimorfismo ad-hoc menos ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Teoremas de graça!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Inicial e Final, DSLs, Finally Tagless - [Codificação Final, Parte 1: Uma breve demonstração](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transformando Valores Polimórficos](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs em Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Cálculo Lambda Linear Tipado Tagless-Final](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Interpretação de tagless-final tipado: Notas de Aula](http://okmij.org/ftp/tagless-final/course/course.html). - [Interpretadores Tagless Final Tipado](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [O cachorro que não latia](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) menos especificamente relevante, mas interessante. ## Comonads - [Comonads em Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [Questão no SO: Uma *monad* pode ser uma *comonad*?](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [Questão no SO: Explicação passo-a-passo de coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - *Free monads for Less*, uma sequência de três artigos por Edward Kmett. * [Parte 1: Codensidade](http://comonad.com/reader/2011/free-monads-for-less/). * [Parte 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Parte 3: Produzindo IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Proposições vs. Julgamentos (computação) - [Questão no StackExchange: Qual a diferença entre proposições e julgamentos?](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Notas de aula de um curso curto, de três aulas](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Tipagem dependente - [Entendendo tipos de soma, construtores de valor, e construtores de tipo](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) difícil de deixar vesgo. - [Programação dependente de tipos leve](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Linguagem de Programação Idris](http://www.idris-lang.org/). # Linkando binários estaticamente - [Linkagem Estática](https://wiki.haskell.org/Web/Literature/Static_linking) - [Linkagem Estática com o GHC no Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Linkando Estaticamente binários do Linux para ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Linkando Estaticamente GMP usando GHC e LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Diálogos > Hospedado [neste](dialogues.md) repositório. Esses são tópicos bastante importantes e úteis. Olhe aqui para mergulhar mais fundo numa variedade de tópicos. ================================================ FILE: guide-ro.md ================================================ # Ghid pentru a învăța Haskell Acest tutorial reprezintă calea recomandată pentru a învăța Haskell, pe baza experiențelor avute ajutând alte persoane. Lista de recomandări este creată de unul din autorii [Haskell Book.](https://haskellbook.com). #### *Nu vă stresați prea mult pentru lucrurile pe care nu le înțelegeți imediat*. Mergeți mai departe! ## Comunitate Canalul de IRC este `#haskell-beginners` de pe Freenode. Un client web the IRC este [aici](http://webchat.freenode.net/). [Lista de discuții](https://wiki.haskell.org/Mailing_lists). ### Recomandări pentru integrarea în comunitate Citiți [lista de sfaturi](coc.md) pentru a înțelege regulile de bună purtare așteptate pe canalul de IRC. Veți primi un avertisment dacă nu sunteți foarte nesimțiți, dar trebuie să știți că acest canal este exclusiv dedicat celor care învață sau predau Haskell. # Instalarea Haskell ## Folosiți Stack pentru a lucra în Haskell Obțineți [Stack](https://haskellstack.org) pentru a instala GHC și a construi proiecte. Dacă nu știți nimic despre Stack și vreți o descriere, vizionați acest [tutorial Stack detaliat](https://www.youtube.com/watch?v=sRonIB8ZStw). ## De asemenea, NU INSTALAȚI HASKELL PLATFORM În loc să urmăriți instrucțiunile de pe Haskell.org, folosiți Stack. ### De ce nu Haskell platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Cum puteți învăța Haskell? Recomandarea principală este să citiți lecrurile și să rezolvați toate exercițiile/temele acasă din versiunea de toamnă, 2013, a cursului cis1940, urmate de a face același lucru și pentru cursul FP. Ambele cursuri sunt referite mai jos. Orice altceva poate fi considerat opțional, celelate referințe de mai jos sunt doar ca să știți unde vă mai puteți uita. ## Alternativ... [@dmvianna](https://github.com/dmvianna) a dorit să vă anunț că recomandările de aici sunt doar resursele _gratuite_. Dacă doriți să citiți o carte, vă recomandăm cu mare placere cartea noastră, [Haskell Book!](https://haskellbook.com). Aceasta înlocuiește în principiu toate recomandările de aici. ## Cursul cis1940 al lui Yorgey > *Treceți prin acest curs prima dată*, acesta este modul principal prin care recomandăm > primul contact cu Haskell. Este disponibil [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Cursul lui [Brent Yorgey](https://byorgey.wordpress.com) este cel mai bun pe care l-am găsit până acum. Este foarte valoros mai ales că nu numai că vă va învăța cum să scrieți cod Haskell de bază dar vă va și ajuta să înțelegi combinatorii de analiză gramaticală. Singurul caz în care acest curs nu este recomandat este dacă nu sunteți programator/programatoare sau nu aveți multă experiență în domeniu. În acest caz, recomandarea este să începeți cu [cartea lui Thompson](https://www.haskellcraft.com/craft3e/Home.html) și să tranziționați ulterior la cis1940. --- ## Cursul FP > Este cursul pe care-l recomandăm după ce ați trecut prin cursul lui Yorgey Este disponibil pe GitHub [aici](https://github.com/bitemyapp/fp-course). Acesta vă va oferi experiența de a implementa abstracțiile din cis1940, o practică **esențială** pentru a fi obișnuiți cu utilizarea comună a Functor/Applicative/Monad/etc în Haskell Principala recomandare a acestui ghid este să treceți întâi prin cis1940 și apoi prin FP și reprezintă exact modul în care noi predăm Haskell. --- ## Cursuri suplimentare după cis1940 și FP > Oferă mai multe materiale pe subiecte de dificultate medie cs240h este disponibil [online](http://www.scs.stanford.edu/14sp-cs240h/). Acesta este cursul online al lui [Bryan O'Sullivan](https://github.com/bos) de la Stanford. Dacă nu știți cine este, uitați-vă la faptul că jumătate din bibliotecile pe care orice aplicație Haskell ajunge să le folosească poartă numele lui. Dacă alegeți să faceți acest curs, importante sunt capitolele legate de phantom types, fluxul informației, extensiile de limbaj, concurență, pipes și lenses. --- # Resourse pentru topicuri specifice în Haskell Aceste resurse nu sunt validate în practică la aceeași profunzime ca cis1940 și FP, dar sunt referite în [lista de topicuri](specific_topics.md) ca să aveți o idee de unde să începeți. Lucruri precum concepte de nivel mediu/avansat și subiecte precum instrumente de dezvoltare și editoare de text sunt incluse. ## Dialoguri > Stocate în repository-ul de [aici](dialogues.md). De fapt, acestea sunt foarte importante și ajută. Citiți aceste dialoguri pentru a aprofunda o varietate de topicuri. ================================================ FILE: guide-ru.md ================================================ # Как познать Haskell Этот документ — рекомендованный путь к изучению языка Haskell, основанный на опыте помощи другим. ## Это руководство доступно на других языках: - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Не мучайтесь над одним топиком, который вы не можете понять сразу*. Двигайтесь дальше! ## Сообщество IRC канал `#haskell-beginners` на Freenode. [IRC веб-клиент](http://webchat.freenode.net/). [Почтовые рассылки](https://wiki.haskell.org/Mailing_lists). ### Политика сообщества [Смотрите пост про обучение от Криса Дона](http://chrisdone.com/posts/teaching). Будьте дружелюбны и вежливы. Грубость и хамство испугает собеседника и оттолкнет от участия в общении. Слабая, неконструктивная критика удовлетворяет лишь критикующего, но не помогает критикуемому. Не описывайте вещи как «легкие» или «тривиальные». Вы заставляете людей чувствовать себя ужасно за то, что они усердно и много работают ради своего прогресса. Медленные в обучении люди зачастую самые дотошные, этому наоборот надо радоваться! Не симулируйте удивление. Не изображайте удивление, когда кто-либо говорит, что он не знает что-то. Он будут чувствовать себя ужасно, а вы не получите ничего, кроме резкости. «Ну, на самом деле». Когда кто-либо говорит что-то почти — но не совсем — верное, а вы говорите «ну, на самом деле...» и даете лишь мелкую правку. Это особенно раздражает, когда поправка не относится к основной теме разговора. Это не значит, что этот канал не про поиск правды или что нам все равно на точность. Просто почти все «ну, на самом деле» являются показухой, а не поиском правды. Не делайте всю работу за обучающегося. Если вы видите, что человек работает над проблемой, вы не должны немедленно выдавать советы или готовые решения. Дайте ему поработать и поизучать, пока он сам не попросит помощи. Избегать помех — [одна из основных причин существования #haskell-beginners](http://chrisdone.com/posts/teaching). Никаких -измов. Расизм, сексизм, гомофобия, трансофобия и другие виды фобий не приветствуются и не будут приняты терпимо. --- [Правила хорошего тона от Recurse Center](https://www.recurse.com/manual). Спасибо за их публикацию Recurse Center. # Что такое Haskell, GHC и Cabal? Haskell — это язык программирования, изложенный в спецификациях, последняя версия которых опубликована в 2010 году. Эта спецификация доступна как [онлайн-документ](http://www.haskell.org/onlinereport/haskell2010/). ## GHC [GHC](http://www.haskell.org/ghc/) — это самый популярный способ работы с языком Haskell. Он включает в себя компилятор, REPL (интерпретатор), пакетный менеджер и другие полезные вещи. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) позволяет управлять проектами и разрешает зависимости. При помощи него вы устанавливаете и создаете проекты, обычно в песочницу (изолированное окружение). Cabal аналогичен Bundler в Ruby, pip в Python, NPM в Node и так далее. GHC управляет пакетами сам, Cabal решает какие версии устанавливать. # Установка Haskell ## НЕ УСТАНАВЛИВАЙТЕ HASKELL PLATFORM Вместо следования инструкциям на Haskell.org, смотри инструкции ниже, как установить GHC и Cabal. # Установка GHC и Cabal ## Ubuntu [Этот PPA](http://launchpad.net/~hvr/+archive/ghc) лучший, и именно его я использую на всех моих серверах и локальных машинах с Linux. А именно: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.22 ghc-7.8.4 happy-1.19.5 alex-3.1.4 ``` После этого, добавьте следующие пути к вашему `$PATH` (bash\_profile, zshrc, bashrc, и т. п.): ``` export PATH=$PATH:~/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.8.4/bin:/opt/happy/1.19.5/bin:/opt/alex/3.1.4/bin ``` *Опционально:* вы можете добавить также `.cabal-sandbox/bin` к вашему пути. Код, который вы разрабатываете, будет доступен вам из командной строки. Это работает только тогда, когда ваша текущая рабочая папка — песочница cabal. ## Debian ### Использование Ubuntu PPA Если вы не используете стабильный дистрибутив, вы можете повторить все те же шаги, что и для Ubuntu, но вам надо будет выполнить дополнительную команду. Сразу после `sudo add-apt-repository -y ppa:hvr/ghc` выполните: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` Для остальных версий Debian, просто замените все `jessie` именем вашей версии в команде выше. Если по какой-то причине файл `/etc/apt/sources.list.d/hvr-ghc-jessie.list` не существует, то `/etc/apt/sources.list` должен содержать строку со ссылкой вроде этой: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Замените `jessie` на `trusty` в этой строке. ### Сборка из исходников Вы можете использовать [это руководство](http://www.davesquared.net/2014/05/platformless-haskell.html), написанное для Mac OS X: Замечания: - Выставьте ваш префикс соответственно, когда конфигурируете ghc. - Вместо того, чтобы забирать бинарник `cabal-install`, скачайте исходный код и запустите скрипт `bootstrap.sh`. ## Fedora 21 Чтобы установить Haskell 7.8.4 из неофициального репо (Fedora 22+ будут содержать его в официальном): ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` Как указано на странице [petersen/ghc-7.8.4](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) этот ghc не может быть установлен вместе с Fedora/EPEL ghc. ## Arch Linux Чтобы установить Haskell из официального репо на Arch Linux, выполните: ```bash $ sudo pacman -S cabal-install ghc happy alex haskell-haddock-library ``` ## Gentoo На Gentoo вы можете установить индивидуальные компоненты Haskell Platform через Portage. Если вы используете `ACCEPT_KEYWORDS=arch` (вместо `ACCEPT_KEYWORDS=~arch`), Portage установит древние версии различных компонент Haskell. Помня это, если вы используете `ACCEPT_KEYWORDS=arch`, добавьте следующие строки в `/etc/portage/package.accept_keywords`. dev-haskell/cabal-install ~arch dev-lang/ghc ~arch Как только это сделано, ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo хранит «стабильную» (читай «старую») версию `cabal-install` в дереве Portage, так что, если вы хотите использовать более современную версию `cabal-install`, выполните (заметьте, что слеши здесь нужны) ```bash $ \cabal update # Слеши здесь $ \cabal install cabal-install # нужны ``` Вы установили cabal глобально через Portage и локально в вашей домашней директории с `cabal-install`. Следующий шаг, это убедиться, что когда вы запускаете `cabal` в вашем терминале, ваша оболочка запускает последнюю версию в вашей домашней директории. Вам нужно добавить следующие строки к конфигурационному файлу вашей оболочки. ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` Если вы не знаете, какая оболочка у вас используется, то скорее всего это Bash. Если это Bash, то файл, в который вам надо добавлять эти строки — `~/.bashrc`. Если вы используете Z-shell, то это `~/.zshrc`. Вы можете понять, какая оболочка у вас используется, запустив: ```bash echo $SHELL | xargs basename ``` Я использую zsh, так что вывод этой команды у меня выглядит как `zsh`. После всего этого вы захотите установить дополнительные инструменты `alex` и `happy`. ```bash $ cabal install alex happy ``` Поздравляю! Теперь у вас рабочий Haskell! ## Mac OS X ### 10.9 Установите [GHC для Mac OS X](http://ghcformacosx.github.io/) приложение, которое включает в себя GHC и Cabal. Оно предоставляет инструкции, как добавить GHC и Cabal в ваш путь, после того как вы скопируете приложение `.app` куда-либо. ### 10.6—10.8 Выполните установку бинарников, которая описана ниже, для [этого архива](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2). ## Windows - [Минимальный установщик GHC для Windows](http://neilmitchell.blogspot.com/2014/12/beta-testing-windows-minimal-ghc.html) способен скомпилировать `network` и т. п. Технически, это бета версия, но должна работать для тех, кто читает это руководство. Не забудьте запустить установщик как администратор, так как он захочет установить файлы в Program Files. ## Пользователям других Linux дистрибутивов Скачайте последние бинарники Cabal и GHC: - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). ## Пользователям других Unix-подобных систем Скачайте GHC и Cabal из вашего пакетного менеджера, затем добавьте `~/.cabal/bin` в ваше `$PATH`. После этого обновите `cabal` и установите дополнительные инструменты `alex` и `happy`. ```bash $ cabal update $ cabal install cabal-install alex happy ``` # Как я должен изучать Haskell? Основная рекомендация, это читать лекции и выполнять все упражнения/домашние задания для Spring 13 версии курса cis1940. Затем то же для курса FP. На оба курса ссылки представлены ниже. Все остальное может быть рассмотрено как опциональное, и вы просто будете знать куда смотреть по определенной теме. ## Курс Yorgey cis1940 > *Выполните его в первую очередь*, это лучший путь получить представление о Haskell Доступен [онлайн](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Курс от [Brent Yorgey](https://byorgey.wordpress.com), это лучшее, что я пока нашел. Этот курс ценен тем, что он не только научит вас писать базовый код на Haskell, но и также поможет вам понять комбинаторы парсера. Единственная причина, по которой вам не стоит начинать с курса cis1940, это если вы не программист или вы неопытный программист. В этом случае, начинайте с [книги от Thompson](https://www.haskellcraft.com/craft3e/Home.html) и после этого уже курс cis1940. --- ## Курс FP > Этот курс мы рекомендуем выполнять после курса Yorgey cis1940. [Доступен на Github](https://github.com/bitemyapp/fp-course). Этот курс укрепит и добавит опыта реализации абстракций, представленных в курсе cis1940. Эта практика *критически важна* для комфортного использования в дальнейшем таких абстракций как Functor/Applicative/Monad/и т. п. в Haskell. Выполнение cis1940 и затем FP курсов представляет собой основную рекомендацию моего руководства и того, как научить любого языку Haskell. --- ## Дополнительный курс после cis1940 и FP > Предоставляет больше информации по продвинутым темам cs240h доступен [онлайн](http://www.scs.stanford.edu/14sp-cs240h/). Это онлайн курс от [Bryan O’Sullivan](https://github.com/bos), который он преподает в Стенфорде. Если вы не знаете кто он такой, взгляните на половину библиотек, от которых зависят все приложения на Haskell, и вы увидите его имя в их авторах. Если вы уже закончили курс Yorgey, особого внимания в этом курсе заслуживают разделы о фантомных типах, контроле потоков информации, расширениях языка, конкурентном выполнении, pipes и линзах. --- # Специфичные топики Haskell Эти источники не были проверены на учащихся так, как cis1940 и FP, но с их помощью вы поймете с чего начинать изучение определенной темы. Они включают продвинутые и сложные темы и топики посвященные инструментам и текстовым редакторам. ### Что делает `<-` / `do` / синтаксический сахар включения списков? Отличная [статья](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html). ### Для понимания списков и свертки - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### Для изучения некоторых из стандартных классов типов Полезно для понимания `Functor`, `Applicative`, `Monad`, `Monoid` и других классов типов в целом, а также немного специфичной для Haskell теории категорий: - The [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Понимание базовых сообщений об ошибках в Haskell - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Laziness, strictness, guarded recursion - [Книга Marlow](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) про параллелизм и конкаренси содержит одно из лучших представлений laziness и нормальных форм, которые я нашел. Используйте другие источники, если не поймете сразу из этого. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Вопрос на Stack Overflow — [Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization) - Слайды [Johan Tibell](https://github.com/tibbe) из доклада [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Краткая демонстрация ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class “statements”](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) При прочтении, обратите внимание на реализацию unsafeDupablePerformIO Комментарий с обсуждения на Reddit от `glaebhoerl` Перевод: > Интересное замечание: GHC должен скрывать отображение токена статуса > абстрактного типа IO, потому что токен статуса должен все время быть использован > линейно (не быть дуплицирован или сброшен), но система типов не может принудительно > этого делать. Clean, другой ленивый подобный Haskell язык, имеет типы, гарантирующие уникальность > (которые подобны линейным типам и возможно отличаются, но я не знаю как), и они разкрывают > передачу в Мир напрямую и предоставляют (не абстрактную) IO монаду только для соблюдения соглашения. Оригинал: > Interesting side note: GHC needs to hide the state token representation behind > an abstract IO type because the state token must always be used linearly (not > duplicated or dropped), but the type system can’t enforce this. Clean, another > lazy Haskell-like language, has uniqueness types (which are like linear types > and possibly different in ways I’m not aware of), and they expose the > World-passing directly and provide a (non-abstract) IO monad only for > convenience. # Монады и трансформеры монад > Не делайте этого пока вы не поняли классы типов Monoid, Funcor и Applicative! Реализуйте монады из стандартной библиотеки (List, Maybe, Cont, Error, Reader, Writer, State) для себя, чтобы понять их лучше. Затем, может быть, напишите монадный интерпретатор для маленького языка выражений используя документ [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf) (упомянут в «трансформеры монад» ниже). Написание многих интерпретаторов просто изменяя монаду для изменения семантики может помочь лучше понять, что происходит. Также, реализуйте `Control.Monad`. Функции типа `mapM` или `sequence` — хорошая возможность попрактиковаться в написании общего кода монад. Курс FP может быть использован как руководство для этого, он также включает написание своего собственного Applicative. Упоминания: - [Комментарии](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6) на Reddit от htmltyp и Crandom. - [Комментарий](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg) на Reddit от jozefg. ## Трансформеры монад - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](http://catamorph.de/documents/Transformers.pdf). # Тестирование, тесты, спеки, generative/property тестирование - Это [руководство](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) от Kazu Yamamoto — просто фантастичecкое. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Хорошая простая библиотека для изучения, как работает стриминг IO в целом, знания, применимые также к таким библиотекам как Pipes и Conduit. # Парсинг в Haskell - [Руководство по Parser комбинаторy](https://github.com/JakeWheat/intro_to_parsing) для Haskell с использованием Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Парсинг и генерация JSON Aeson — это стандартное решение для парсинга [JSON](https://json.org) в Haskell. Доступно из [hackage](https://hackage.haskell.org/package/aeson) и [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson tutorial](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Алгоритмы графов и структуры данных - [Пакет fgl](https://hackage.haskell.org/package/fgl) частично чисто функциональный кратчайший путь [algos](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell — A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph source from Containers package](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - [Пакет graphs](https://hackage.haskell.org/package/graphs). - [SO вопрос про PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS бесплатно](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Окружение разработки ## Emacs - [Alejandro Serras’s tutorial](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [My dotfiles](https://github.com/bitemyapp/dotfiles/) - [Chris Done’s emacs config](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim page on haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Работа с Cabal ## Руководства по Cabal Cabal Hell был проблемой для пользователей Haskell до появления песочниц (sandboxes). Установка вне песочницы происходит в вашу пользовательскую базу данных пакетов. Это *не очень* хорошая идея, за исключением основных пакетов, таких как Cabal, alex и happy. Более ничто не должно быть установлено глобально или в пользовательскую базу данных пакетов, если вы не уверены в том, что делаете. [Советы](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html) как избежать cabal hell. Для экспериментов с пакетом или в начале нового проекта, начните с команды `cabal sandbox init` в новой папке. Кратко: - Всегда используйте песочницы для установки новых пакетов, создания новых проектов, или для экспериментов. - Используйте `cabal repl` для использования ghci внутри проекта. Основанный на песочницах подход, который я советую, поможет избежать проблем с зависимостями пакетов, но он не совместим со способом, предоставляемым Haskell Platform для собранных пакетов. Если вы все еще изучаете Haskell и не понимаете как ghc-pkg и Cabal работает, *избегайте платформу* и вместо этого используйте инструкции по установке, описанные выше. ## Stackage Для любых пользователей (обычно для пользователей Yesod), которые испытывают проблемы со сборкой, существует Stackage. - [Хороший обзор Stackage](https://www.fpcomplete.com/blog/2014/05/stackage-server). По мнению автора, Stackage обычно более полезен, чем `cabal freeze`. # Hoogle и Haddock ## Поиск кода по сигнатуре типов [Поисковый движок Hoogle](http://www.haskell.org/hoogle/) может искать по типам. Например, взгляните на результат поиска для [`(a -> b) -> [a] -> [b]`](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Так же он доступен [на fpcomplete](https://www.fpcomplete.com/hoogle). Еще есть [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (который включает все пакеты hackage для поиска по дефолту). ## Разворачивание собственного локального Hoogle Взгляните [сюда](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Hackage documentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Заметьте, что эти публикации *слегка устарели*: например, теперь Hackage поддерживает новую информацию с информацией о документации и статус сборки. ## Что вам правда нужно знать Чтобы haddock включал документацию для зависимых пакетов, вам нужно выставить `documentation: True` в вашем `~/.cabal/config`. Если это было выставлено по дефолту (`False`) или выставлено непосредственно в `False`, вам нужно будет удалить все ваши пакеты и переустановить перед генерацией haddock. Другая вещь, о которой надо помнить, это то, что из-за способа, которым `$pkg` параметр интерполируется *посредством* cabal, не вами, `html-location` и `content-location` параметры *должны быть в одиночных кавычках* и набираться в оболочке или содержаться в shell-скрипте. Они не будут работать в Makefile, потому что haddock будет думать, что они являются переменными Make! ```bash #! /usr/bin/env sh # Вы можете набирать это одной строкой без обратных слешей cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Если вы такой же большой фанат [TravisCI](https://travis-ci.org) как я, тогда *очень* рекомендую вам взглянуть на [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) как основу для `travis.yml` ваших Haskell проектов. # Frontend/JavaScript Мы обладаем огромными богатствами! Есть три основных вещи, которые я рекомендую: * [Haste](http://haste-lang.org/) компилятор Haskell в JavaScript - [Компилятор](https://github.com/valderman/haste-compiler) на github - [Отличное демо](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) Haste с примером проекта * [GHCJS](https://github.com/ghcjs/ghcjs) - [GHCJS Introduction](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Не совсем Haskell как Haste или GHCJS, но популярный выбор многих пользователей Haskell. - Написан и вдохновлен языком Haskell. - Попробуйте [PureScript](http://try.purescript.org/) в вашем браузере. - Отличное руководство для [начала](https://www.christopherbiscardi.com/2014/6/22/getting-started-with-purescript/). ## Какой фронтенд язык мне использовать? GHCJS и Haste оба являются полноценным Haskell. GHCJS будет работать с большим числом пакетов, нежели Haste, но это не затрагивает большинство фронтенд проектов. PureScript совсем не Haskell, так что использовать Haskell код из вашего бекенда совсем не получится. GHCJS имеет самое быстрое время выполнение на уровне 100kb (luite работает на этом). Haste и PureScript сравнимы. PureScript имеет наилучшую интеграцию с JS инструментами (использует gulp/grunt/bower), GHCJS и Haste интегрируются лучше с инструментами Haskell (Cabal). Все три являются отличным выбором и будут работать для большинства фронтэнд проектов. # Для более глубокого понимания laziness, NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus) ## Исследовательские документы про lazy lambda calculi - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal) - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf) - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Parallelism/Concurrency - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929). Эта книга от Simon Marlow, наверное лучшее, что я когда-либо читал о параллелизме и конкаренси. - Хорошее [руководство](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) по тестированию и инкрементальной разработке многопоточного приложения в Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming). # Линзы и призмы Как только вы почувствуете себя комфортно с Haskell, очень рекомендую изучить Lenses и Prisms, даже лишь в качестве «пользователя». Вам не обязательно нужно понимать лежащую в основе категорию для того, чтобы они были полезны. Люди зачастую завышают сложность использования линз. Все, кто комфортно чувствует себя используя Functor/Foldable/Traversable (или даже если лишь первый) могут начать использовать линзы и призмы для облегчения своей жизни. Если вы когда-либо делали что-то вроде: `(fmap . fmap)`, вы уже «использовали линзы» в своей голове. Я рекомендую следующие два руководства: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) За дальнейшей информацией смотрите: [Lens package on hackage](http://hackage.haskell.org/package/lens). # Схемы рекурсии Некоторые сумасшедшие \*-morphism слова, которые вы могли слышать, на самом деле о рекурсии. Но перед тем как трогать этот материал, вы должны знать как реализовать foldr для списков и хотя бы одну структуру данных, такую как дерево. (folds являются catamorphisms). Знание о том, как реализовать unfold (anamorphism), также помогут в осознании этих вещей. Этот материал согласуется с traversable и foldable. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don’t fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) — хорошая демонстрация того, как hylomorphism, это композиция из cata и ana - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) — это руководство просто замечательно! - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # Ядро GHC и настройка производительности - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType) - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core) - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core) - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/) - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html) # Тип и теория категорий > *Не* необходимо для работы с Haskell, просто для тех, кто интересуется! Если вы хотите вникнуть в типы и теорию категорий: - [Catster’s Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) и [Catster’s Guide 2](http://byorgey.wordpress.com/catsters-guide-2/). - [Вики-книга haskell](http://en.wikibooks.org/wiki/Haskell/Category_theory) содержит неплохие диаграммы. - [Category Theory](http://www.haskell.org/haskellwiki/Category_theory) на haskellwiki, также содержит хорошие ссылки. - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), содержит несколько практических примеров. - Список Pierce [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml). ## Книги - Рекомендации Kmett: [Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) и [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Стандартные книги про теорию категорий. - [Harper’s Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) лучшее PL интро к теории типов, которое я читал. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Другие веселые темы ## Parametricity, ad-hoc vs. parametric polymorphism, free theorems - [Parametricity](tony_parametricity.pdf). - [Исходники в TeX](https://github.com/tonymorris/parametricity/) для доклада выше. - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf) ## Initial and Final, DSLs, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn’t bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) less specifically relevant but interesting. ## Comonads - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell) - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad) ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Свободные монады для Less, серия из трех публикаций от Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/) * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/) * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/) ## Propositions vs. Judgments (computation) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments) - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Зависимая типизация - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) squint hard - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html) - [Idris programming language](http://www.idris-lang.org/) # Statically linking binaries - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Диалоги > Хранятся в этом репозитории [в dialogues.md](dialogues.md). Они на самом деле достаточно важны и полезны. Просмотрите для погружения в некоторые из тем. ================================================ FILE: guide-sr.md ================================================ # Kako učiti Haskell Ovo je preporučeni put za učenje Haskell-a zasnovan na iskustvu u pomaganju drugim ljudima. Ovo je lista preporuka jednog od autora [Haskell knjige](https://haskellbook.com) ## Za one koji ne govore Srpski - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Ne obraćajte mnogo pažnju na stvari koje ne razumete iz prve*. Samo idite napred! ## Zajednica Naš IRC kanal je `#haskell-beginners` na Freenode-u. IRC web [klijent](http://webchat.freenode.net/). Haskell [email lista](https://wiki.haskell.org/Mailing_lists). ### Smernice zajednice Pogledajte [smernice zajednice](coc.md) da bi razumeli kakvo ponašanje se očekuje na IRC kanalu. Bićete upozoreni ako očigledno "trolujete" , ali budite svesni toga da kanal služi isključivo onima koji uče ili podučavaju Haskell. # Instaliranje Haskell-a ## Koristite Stack da bi krenuli sa Haskell-om Preuzmite [Stack](https://haskellstack.org) da bi uz pomoć njega instalirali GHC za bildovanje projekata. Ako ne znata ništa o Stack-u a želeli biste da saznate, pogledajte ovo [Stack video tutorial](https://www.youtube.com/watch?v=sRonIB8ZStw). ## Takodje, NEMOJTE INSTALIRATI HASKELL PLATFORMU Umesto da pratite uputstva sa Haskell.org instalirajte Stack. ### Zašto ne platforma ? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Kako da učim Haskell? Glavna preporuka je da pročitate lekcije i završite sve vezbe iz Spring 13 verzije cis1940 kursa posle koga ide FP kurs. Oba linka su ispod. Sve ostalo može da se smatra opcionim i pomenuto je ovde da bi znali gde da tražite resurse. ## Alternativno... [@dmvianna](https://github.com/dmvianna) je želela da napomenem da su ovo samo besplatni i preporučeni resursi, ako ste zainteresovani da pogledate knjigu preporučujemo od sveg srca našu [Haskell Knjigu!](https://haskellbook.com) Ova knjiga zamenjuje sve pomenuto. ## Yorgey-jev cis1940 kurs > *Pročitajte ovo prvo*, ovo je primarni način koji preporučujemo za upoznavanje sa Haskell-om Dostupno [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com)-jev kurs je najbolji kurs koji sam video do sada. Ovaj kurs je vredan zato što ne samo da će Vas spremiti da pišete osnovni Haskell već će i pomoći da razumete parser kombinatore. Jedini razlog da ne počnete sa cis1940 kursom je ako niste programer ili ste programer sa malo iskustva. U tom slučaju počnite sa [Thompson-ovom knjigom](https://www.haskellcraft.com/craft3e/Home.html) i posle predjite na cis1940. --- ## FP kurs > Ovo je kurs koji preporučujemo posle Yorgey-jevog cis1940 kursa Dostupan je na github/u [ovde](https://github.com/bitemyapp/fp-course). On će utvrditi iskustvo u direktnom implementiranju abstrakcija koje su uvedene u cis1940 kursu. Ovo je praksa koja je *kritična* da bi se osećali prijatno sa svakodnevnom upotrebom Fanktora/Aplikativa/Monada itd. u Haskell-u. Glavna preporuka ovog vodiča je da predjete cis1940 a zatim FP kurs i to je način na koji učimo Haskell sve zainteresovane. --- ## Dodatni kurs posle cis1940 i FP > Sadrži više materijala o srednje naprednim temama cs240h je dostupan [online](http://www.scs.stanford.edu/14sp-cs240h/). Ovo je [Bryan O'Sullivan](https://github.com/bos)-ov online kurs kojim on predaje na Stanford-u. Ako ne znate ko je on bacite oko i videćete da je njegovo ime na pola Haskell biblioteka koje se potrebne bilo kojem Haskell programu. Naročito treba pomenuti, ako ste već završili Yorgey-jev kurs, module sa fantomskim tipovima, kontrola toka informacija, ekstenzije jezika, konkurentnost, pipes i lenses biblioteke. --- # Resursi za specifične teme u Haskell-u Ovi resursi nisu testirani sa učenicima kao što su kursevi cis1940 i FP ali se nalaze u [listingu tema](specific_topics.md) tako da imate predstavu odakle da krenete. Ovo uključuje srednje/napredne koncepte i teme kao što su alati i tekst editori. ## Dijalozi > Nalaze se u ovom repozitorijumu [ovde](dialogues.md). Ovo je naročito važno i korisno. Ovo je dublji pregled različitih tema. ================================================ FILE: guide-tl.md ================================================ #Paano matuto ng Haskell Ito ay ang maipapayong daan upang matutunan ang Haskell base sa karanasan na makatutulong sa iba. Mayroong listahang ng mga rekomendasyon sa isa sa mga may akda ng [Haskell Book.](https://haskellbook.com) ## Para sa mga di nag-Iingles - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Türkçe](guide-tr.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Wag kang kabahan sa mga bagay na hindi mo naiintindihan agad*. Mag-patuloy ka lamang! ## Komunidad Ang aming IRC channel ay `#haskell-beginners` sa Freenode. Kliyenteng pang-websayt [dito](http://webchat.freenode.net/). Haskell,[listahan ng padadalhan ng sulat](https://wiki.haskell.org/Mailing_lists). ### Patakaran ng Komunidad Tignan [ang patakaran ng komunidad](coc.md) upang malaman ang adhikain sa IRC channel. Mabibigyan ka ng babala kung hindi ka halatang nanloloko, ngunit maging maingat sapagkat ang channel ay para lamang sa mga gustong matuto o nag-tuturo ng Haskell. # Pag-iinstall ng Haskell ## Gamitin ang Stack upang makapag simula sa Haskell I-install ang [Stack](https://haskellstack.org) upang ma-install ang GHC para makapagtayo ng sariling proyekto. Kung wala kang alam sa kahit ano mang bagay tungkol sa Stack at gustong matuto tungkol dito, tignan itong [unawaan ng Stack bidyo tutorial](https://www.youtube.com/watch?v=sRonIB8ZStw) ## WAG I-INSTALL ANG HASKELL PLATFORM Datapwa't sundin lamang ang instruksyon sa Haskell.org para makuha ang Stack. ### Bakit hindi ang platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Paano ko pag-aaralan ang Haskell? Ang pinaka-rekomendasyon ay basahin ang mga lektura at tapusin ang mga pagsasanay/takdang aralin para sa Spring 13 version ng cis1940 tapos ang kurso ng FP. Ang dalawa ay naka-takda sa ibaba. Ang iba ay hindi na kailangan ngunit ini-mungkahi para sa iyong kapakanan. ## Haskell Programming from First Principles. I-Pinapaalam ni [@dmvianna](https://github.com/dmvianna) na ang mga nasa babaya _libreng_ mga rekomendasyon pang-kaalaman. Kung gusto mong tumingin ng libro, inirerekomenda na kumuha ng iyong sariling [Haskell Book](https://haskellbook.com). Kung hindi mo makakayang bilhin ang libro sa anumang dahilan, maaaring mag-sumite saamin ng email gamit ang [aming pahinang pang-suporta](https://haskellbook.com/support.html). ### Ang Haskell Book ay nilalathala ang lahat ng primerong mapagaaralan dito ## Kursong cis1940 ni Yorgey > *Talakayin muna ito* kung hindi mo bibilhin ang Haskell Book, ito ay ang pinakamagandang _libreng_ introduksyon sa Haskell. Makukuha [online](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Ang kurso ni [Brent Yorgey](https://byorgey.wordpress.com) ay ang pinakamaganda sa pagkakaalam ko. Itong kurso ay mahalaga dahil hindi ka lamang tuturuan mag-sulat ng pinakapundomental na Haskell ngunit matutulungan karin maintindihan ang mga parser combinators. Ang tanging dahilan para wag mag-simula sa cis1940 ay kung ikaw ay hindi programmer o hindi eksperyensado. Kung yun ang kaso, mag-simula sa [Libro ni Thompson](https://www.haskellcraft.com/craft3e/Home.html) at tyaka lumipat sa cis1940. --- ## Kurso ng Functional Programming > Ito ang inirerekomenda naming kurso pagkatapos ng Kursong cis1940 ni Yorgey Makukuha sa [dito](https://github.com/bitemyapp/fp-course) sa github. Ito ay magbibigay lakas at karanasan sayo sa pag-implementa ng kabasalan na itinuro sa cis1940, ito ay isang gawi na *kritikal* upang maing kumportable sa pang-araw araw na pag-gamit ng Functor/Applicative/Monad/etc. sa Haskell. Ang pag-talakay sa cis1940 at sa FP course ay ang nag-rerepresenta ng ubod ng rekomendasyon ng aking patnubay at kung paano kami nag-tuturo ng Haskell sa lahat. --- ## Dagdag kurso pagkatapos ng cis1940 at FP course > Nag-bibigay kaalaman sa mga nakalalalim ng paksa. Makukuha ang cs240h online: * [Spring 14](http://www.scs.stanford.edu/14sp-cs240h/) * [Winter 16](http://www.scs.stanford.edu/16wi-cs240h/) Ito ay mga online na kurso ni [Bryan O'Sullivan](https://github.com/bos) mula sa klaseng tinuturuan niya sa Stanford. Kung hindi mo siya kilala, Silyapan lamang ang kalahati ng aklatan ng kahit anong Haskell application at makikita mo ang kanyang ngalan. Kung nasagawa mo na ang Kurso ni Yorgey nanduon ang modules sa phantom types, information flow control, language extensions, concurrency, pipes, at lenses. --- # Pang-kaalaman para sa tiyak na paksa sa Haskell Ang mga mapagkukunan na ito ay hindi tiyak para sa mga nag-aaral di katulad ng cis1940 at FP course, ngunit sila'y linked in [sa listahan ng paksa](specific_topics.md) upang ikaw ay mag-ka ideya kung saan mag-sisimula. Naisasama dito ang mga intermediate/advanced na ideya at paksa katulad ng tooling at text editors. ## Dalwausap > Naisalagay dito sa repository [dito](dialogues.md). Ito ay napakamatulungin at importante. Tignan dito para sa mga malalalim na mga uri ng paksa. ================================================ FILE: guide-tr.md ================================================ # Nasıl Haskell Öğrenirim - Kılavuz Başkalarına yardım ederek deneyimlenmiş, Haskell öğrenmek için önerilen yöntemdir. [Haskell Book](http://haskellbook.com) kitabının yazarlarından birine ait önerilerin listesidir. ## Türkçe Bilmeyenler İçin - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Українською](guide-ua.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### _Anlamadığın şeyleri hemen başına dert etme_. Devam et! ## Topluluk İnternet söyleşi kanalımıza Freenode üzerinden `#haskell-beginners` etiketi ile ulaşabilirsiniz. İnternet söyleşi kanalımızın ağ istemcisi [için](http://webchat.freenode.net/). Haskell [e-posta listesi](https://wiki.haskell.org/Mailing_lists). ### Topluluk Kuralları [Chris Done'ın eğitim hakkındaki gönderisine göz atın](http://chrisdone.com/posts/teaching) Nazik ve kibar olun. Kabalık ve edepsizlik insanları korkutur ve onları iletişime katkı yapmalarını engeller. Yapıcı olmayan eleştiriler sadece söyleyene yarar sağlar, dinleyene değil. Olayları "çok basit" veya "önemsiz" olarak nitelendirmeyin. Bu şekilde insanlar sıkı çalışmaları gerektiğinde kötü hissederler. Yavaş öğrenen kişiler genellikle titizlerdir ve bu övülmesi gereken bir şeydir! Şaşırmış gibi yapmayın. Birisi size bir şeyi bilmediğini söylediğinde şaşırmış numarası yapmayın. Bu durumda karşınızdaki berbat hisseder ve siz de kendinizi uyanık hissetmekten başka hiçbir şey elde etmezsiniz. "Aslında..." cümlesini kurmayın. Biri, çoğunluğu doğru olan - fakat tamamı değil - bir şey söylediğinde, siz de, "Aslında…" diyip küçük bir düzeltme yaparsınız. Bu özellikle yapılan düzeltme ana konuyla alakasız bir şey olduğu zaman irite edici olabilir. Ayrıca bu durum #haskell-beginners kanalının doğruluğa ve kusursuz olmaya önem vermeyen bir kanal olduğu anlamına gelmez. "Aslında ..." diye başlayan cümlelerin çoğu gösterişle alakalıdır, doğruluğa ulaşmakla alakalı değildir. Üzerinize vazife olmayan konularda akıl vermeyin. Bir problemi çözmeye çalışan kişiler gördüğünüzde hemen araya kendi tavsiyelerinizi sıkıştırmaya çalışmayın. Biri yardım isteyene kadar onları çalışmalarıyla başbaşa bırakın. Birbirinin sözünü kesmeden konuşmak [#haskell-beginners kanalının kuruluş amaçlarından biridir](http://chrisdone.com/posts/teaching). Irkçılık, seksistlik, homofobi, transfobi, veya herhangi bir önyargı ya da nefret söylemi hoş karşılanmayacak ve kesinlikle müsamaha gösterilmeyecektir. --- İlkeler [Recurse Center](https://www.recurse.com/manual) 'ın yayınladığı kılavuzdan alınmıştır. Recurse Center'a yayınladığı için teşekkürler! # What are Haskell, GHC, and Cabal? Haskell raporlarda belirtildiği üzere bir programlama dilidir, son sürümü 2010 yılında çıkmıştır. Rapora [buradan](http://www.haskell.org/onlinereport/haskell2010/) ulaşabilirsiniz. ## GHC [GHC](http://www.haskell.org/ghc/) , Haskell çalışmak için en yaygın yoldur. Derleyicinin yanında, REPL (yorumlayıcı - "interpreter"), paket yöneticisi, ve diğer yararlı şeyleri kapsar. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) proje yönetimini ve bağımlılık çözümünü yapar. Cabal ile projeleri oluşturabilir ve genellikle kendi yalıtılmış ortamına ("sandbox") indirebilirsiniz. Cabal Ruby'deki Bundler, Python'daki pip, Node'daki NPM ve Maven'e eş değerdir. GHC paketleri yönetir, Cabal hangi sürümlerin kurulacağına karar verir. # Haskell Kurulum Rehberi ## Haskell'e başlamak için Stack kullanın GHC indirmek ve projelerinizi oluşturmak için [Stack'ı edinin](http://haskellstack.org) . Eğer Stack hakkında hiçbir bilginiz yoksa ve genel bir tanıtıma ihtiyacınız varsa, kapsamlı Stack video eğitimine [buradan](https://www.youtube.com/watch?v=sRonIB8ZStw) ulaşabilirsiniz. ## HASKELL PLATFORM İNDİRMEYİN Haskell.org'da bulunan yönergeyi izlemek yerine Stack edinin. ### Neden Haskell Platform kullanmıyoruz? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Aşağıdaki yönergeler artık kullanılmamaktadır Aşağıdaki yönergeleri izlemek yerine [Stack](http://haskellstack.org) edinmenizi öneriyoruz, fakat asgari düzeyde kurulum yapmak isteyenler için yönergeler muhafaza edilmektedir. # GHC & Cabal Kurulumu ## Ubuntu [Bu arşiv (PPA)](http://launchpad.net/~hvr/+archive/ghc) mükemmel ve tüm Linux makinelerimde bunu kullanıyorum. Yani: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.24 ghc-7.10.3 happy-1.19.5 alex-3.1.4 ``` Ardından aşağıdakini `$PATH` değişkeninize ekleyin (bash\_profile, zshrc, bashrc, etc): ``` export PATH=~/.cabal/bin:/opt/cabal/1.24/bin:/opt/ghc/7.10.3/bin:/opt/happy/1.19.5/bin:/opt/alex/3.1.4/bin:$PATH ``` *Opsiyonel:* Path değişkeninize `.cabal-sandbox/bin` de ekleyebilirsiniz. Geliştirdiğiniz koda komut satırından erişebilirsiniz. Bu sadece şu anda çalıştığınız dizin Cabal sandbox ise çalışır. ## Debian ### Ubuntu PPA kullanarak Eğer stabil sürümü kullanmıyorsanız, Ubuntu'daki adımları olduğu gibi yapabilirsiniz, fakat ekstradan bir komut daha çalıştırmanız gerekecek. `sudo add-apt-repository -y ppa:hvr/ghc` çalıştırıldıktan hemen sonra aşağıdaki kodu çalıştırın: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` Diğer Debian sürümleri için, yukarda gördüğünüz komuttaki bütün `jessie`'leri kendi sürümünüzün adıyla değiştirin. Herhangi bir sebepten ötürü, `/etc/apt/sources.list.d/hvr-ghc-jessie.list` dosyası yoksa, `/etc/apt/sources.list` dosyası aşağıdaki gibi bir satır içermelidir: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Bu satırda `jessie` yerine `trusty` yazın. ### Manuel compilation Mac OS X için yazılmış olan [buradaki](http://www.davesquared.net/2014/05/platformless-haskell.html) kılavuzu kullanabilirsiniz: Not: - GHC'yi yapılandırırken ön eklerinizi (prefix) de düzenleyin. - `cabal-install` dosyası yerine, kaynağı indirin ve `bootstrap.sh` komut dizisini çalıştırın. ## Fedora 21 Haskell 7.8.4 sürümünü resmi olmayan repodan kurmak istiyorsanız (Fedora 22+ resmi sürümü içerir): ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` [petersen/ghc-7.8.4 copr page](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) 'de bahsedildiği gibi bu ghc, Fedora/EPEL ghc ile birlikte kurulamaz. ## Arch Linux Haskell'i Arch Linux'ün resmi reposundan indirip kurmak için aşağıdaki komutu çalıştırın: ```bash $ sudo pacman -S cabal-install ghc happy alex haddock ``` ## Gentoo Gentoo'da, Haskell Platform'un parçalarını Portage aracılığı ile ayrı ayrı kurabilirsiniz. Eğer `ACCEPT_KEYWORDS=arch` kullanırsanız ( `ACCEPT_KEYWORDS=~arch` yerine) Portage, Haskell'deki eski bazı şeyleri de kuracaktır. Bunu göz önünde bulundurarak, sadece ve sadece `ACCEPT_KEYWORDS=arch` kullanacaksanız, aşağıdaki satırları `/etc/portage/package.keywords` dosyasına ekleyin. dev-haskell/cabal-install dev-lang/ghc Bunu tamamladıktan sonra aşağıdaki komutları çalıştırın: ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo `cabal-install`'ın "stabil" (diğer bir tabirle: eski) bir sürümünü Portage ağacında tutar. Eğer `cabal-install`'ın daha yeni bir sürümü kullanmak istiyorsanız aşağıdaki komutları çalıştırın. Burada "\" işaretlerinin gerekli olduğuna dikkat edin. ```bash $ \cabal update # Ters eğik çizgiler $ \cabal install cabal-install # gereklidir. ``` Şu anda Cabal'ı Portage kullanarak global şekilde ve `cabal-install` kullanarak ana dizininize kurdunuz. Sonraki adım terminalde `cabal` çalıştırdığınızda shell'in ana dizininizdeki güncel sürümü çalıştırdığından emin olmak Bunu da aşağıdaki satırları shell'in konfigürasyon dosyası ekleyerek yapabilirsiniz: ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` Shell'in ne olduğunu bilmiyorsanız, büyük bir ihtimalle,shell Bash olarak geçmektedir. Eğer Bash kullanıyorsanız, düzenleyeceğiniz dosya `~/.bashrc` olmalı. Eğer Z-shell kullanıyorsanız, dosyanın ismi `~/.zshrc`. Kullandığınız shell'in ne olduğunu öğrenmek için aşağıdaki komutları çalıştırabilirsiniz. ```bash echo $SHELL | xargs basename ``` Örneğin ben zsh kullanıyorum, bu yüzden komutu çalıştırdığımda `zsh` yanıtını aldım. Bunların hepsini yaptıktan sonra, ek araçlar olarak `alex` ve `happy` kurun. Bunun için: ```bash $ cabal install alex happy ``` Tebrikler! Şu anda çalışan bir Haskell kurulumuna sahipsin! ## Mac OS X ### 10.9 GHC ve Cabal içeren [GHC for Mac OS X](http://ghcformacosx.github.io/) uygulamasını kurun. Uygulamada, `.app` dosyasını bir yere koyduktan sonra GHC ve Cabal'ı path değişkenine nasıl ekleyeceğinizi anlatan yönergeleri de bulabilirsiniz. ### 10.6-10.8 [Buradaki tar dosyasını](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2) indirip kurulumu gerçekleştirin. ## Windows - [Minimum GHC Installer](https://github.com/fpco/minghc#using-the-installer) `network` kütüphanesini ve diğer kütüphaneleri derleyebilmektedir. Minimal GHC ortamının ("environment") yanında Cabal ve MSYS'yi ( `network` gibi kütüphaneleri indirmenize yarayan derleyici ortamı) de içerir. [minghc](https://github.com/fpco/minghc) web sayfasında birkaç detaya rastlayabilirsiniz, fakat normal olanın tüm sistem dizini yerine sadece local AppData dizinine kurmanız olduğunu unutmayın. (C:\Users\\AppData\Local\Programs) ## Diğer Linux Kullanıcıları Cabal and ghc'nin son sürümlerini aşağıdaki linklerden indirebilirsiniz: - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). ## Diğer Unix-benzeri Sistem Kullanıcıları Paket yükleyicinizden GHC ve Cabal'i indirip kurun, sonra `$PATH` değişkeninize `~/.cabal/bin` dizinini atayın. Son olarak `cabal`'ı güncelleyin ve `alex` ve `happy`'i kurun. ```bash $ cabal update $ cabal install cabal-install alex happy ``` # Nasıl Haskell öğrenmeliyim? Ana tavsiyemiz, cis1940 kursunun Bahar'13 versiyonundaki ve İşlevsel Programlama kursundaki dersleri okumanız ve tüm alıştırma/ödevleri tamamlamanızdır. İkisini de aşağıda bulabilirsiniz. Bunlar dışındaki her şey opsiyoneldir ve size nereye bakmanız gerektiğiyle ilgili fikir vermek için bahsedilmiştir. ## "Haskell Programming from First Principles" - Kitap. [@dmvianna](https://github.com/dmvianna) size tavsiye edilen kaynaklardan sadece _ücretsiz_ olanlarının aşağıda olduğunu hatırlatmamı istedi. Eğer bir kitap incelemek istiyorsanız, kendimize ait [Haskell Book!](http://haskellbook.com) kitabını içtenlikle öneririz. Herhangi bir sebepten ötürü kitabın ücretini karşılayamıyorsanız, lütfen [destek sayfamızdaki](http://haskellbook.com/support.html) iletişim bilgilerini kullanarak bize mail atın. ### "Haskell Book" Kitabı burada önerilen birincil kaynakların hepsini içerir. ## Yorgey'in cis1940 kursu > _Bununla başlayın;_ Eğer "Haskell Book" kitabını almayı düşünmüyorsanız bu kurs Haskell'e giriş için en iyi _ücretsiz_ kaynak. Çevrimiçi [erişim](http://www.seas.upenn.edu/~cis1940/spring13/lectures.html). [Brent Yorgey](https://byorgey.wordpress.com)'in kursu şu ana kadar bulabildiğim en iyi kurs. Bu kurs sadece Haskell yazmayı öğretmekle kalmayıp üstüne "Parser Combinator"ler hakkında bilgi sahibi olmanızı sağladığından dolayı çok değerli bir kaynak. Eğer bilgisayar programcısı değilseniz veya yeterince deneyminiz yoksa cis1940 kursuyla başlamanızı tavsiye etmiyoruz. Bu durumda [Simon Thompson'ın kitabıyla](http://www.haskellcraft.com/craft3e/Home.html) başlayıp daha sonra cis1940 kursuna geçin. --- ## İşlevsel Programlama Kursu > Bu kursu Yorgey'in cis1940 kursunu tamamladıktan sonra öneriyoruz. Kursa github üzerinden erişmek için [tıklayınız](https://github.com/bitemyapp/fp-course). Bu kurs cis1940 kursunda bahsedilen kavramları uygulayarak size deneyim katacak ve Haskell'deki Functor/Applicative/Monad/vb. kavramlarını rahatça kullanmanıza _kritik_ düzeyde katkı sağlayacak bir kurs. cis1940 ve ardından İşlevsel Programlama kursunu tamamlamak benim tavsiyelerimin özünü oluşturuyor ve biz herkese Haskell'i bu şekilde öğretiyoruz. --- ## Tamamlayıcı Kurs - cis1940 ve İşlevsel Programlama kursundan sonra > Orta seviye konularda daha fazla materyal içerir cs240h kursuna çevrimiçi olarak aşağıdaki linklerden erişebilirsiniz: - [Spring 14](http://www.scs.stanford.edu/14sp-cs240h/) - [Winter 16](http://www.scs.stanford.edu/16wi-cs240h/) Bu kurs [Bryan O'Sullivan](https://github.com/bos) 'ın Standford'da verdiği derslerin online derlenmiş hali. Eğer kendisinin kim olduğunu bilmiyorsanız, herhangi bir Haskell uygulamasının kütüphanelerine göz atın. En az yarısında ismine rastlayacaksınızdır. Eğer Yorgey'in kursunu tamamladıysanız phantom types, bilgi akışı kontrolü, dil eklentileri, concurrency, pipes, ve lenses hakkındaki modüller ilginizi çekebilir. --- # Haskell'deki Belirli Konular için Kaynaklar Bu kaynaklar cis1940 and IP kurslarının aksine test edilmemiştir, yine de [konu listesi](specific_topics.md)'den nereden başlamanız gerektiğine dair bilgi alabilirsiniz. Belgede orta/ileri düzeydeki konseptleri ve "işleme" ve "metin editörleri" gibi konuları bulabilirsiniz. # Araçlar ## Eğer acemiyseniz ghc-mod indirmeyin ve kullanmaya çalışmayın Biraz kırılgan ve daha yavaştır, çaba sarfetmeye değmez. ## Text Editors - Emacs - [haskell-mode yükleyin](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L31) - [flycheck yükleyin](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L29) - Haskell'i etkinleştirin ve ayarlayın, diğer şeyleri önemsemiyorsanız `(require 'haskell)` modülünü gerektirir. - [flycheck'i etkinleştirin](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L97) - Stack'in `/usr/bin` dizinine kısayol bağlantısını yapın veya flycheck'in onu görebildiğinden emin olun. - [dunzo.](https://twitter.com/bitemyapp/status/693621160571985920) - Vim - Biz [Stephen Diehl'in vim yönergesini](http://www.stephendiehl.com/posts/vim_2016.html) öneriyoruz fakat şimdilik ghc-mod'u aşağıdaki satırlarla değiştirin. - Vim'de type hatalarını eksiksiz biçimde almak için (ghc-mod yerine) ``` autocmd FileType haskell setlocal makeprg=stack\ build autocmd FileType haskell setlocal errorformat=%f:%l:%v:%m ``` - [Sublime Text](https://github.com/SublimeHaskell/SublimeHaskell) - [Atom](https://atom.io/packages/ide-haskell) - [IntelliJ](https://github.com/carymrobbins/intellij-haskforce) - Notepad++, Haskell destekler. - gedit, Haskell destekler. ## Other - Haskell For Mac ## Diyaloglar > [Burada](dialogues.md) muhafaza edilmektedir. Bu diyaloglar aslında çok önemli ve öğreticidir. Birçok konuda derin sohbetler için buraya bakabilirsiniz. ================================================ FILE: guide-ua.md ================================================ # Як вивчати Haskell Цей документ є рекомендованим шляхом вивчання Haskell, який ґрунтується на досвіді допомоги іншим. Список рекомендацій від одного з авторів [HaskellBook](https://haskellbook.com/). ## Інші переклади - [In English](README.md) - [Auf Deutsch](guide-de.md) - [En Español](guide-es.md) - [En Français](guide-fr.md) - [Na Hrvatskom](guide-hr.md) - [Bahasa Indonesia](guide-id.md) - [In Italiano](guide-it.md) - [日本語](guide-ja.md) - [한국어](guide-ko.md) - [Em Português](guide-pt.md) - [În Română](guide-ro.md) - [По-русски](guide-ru.md) - [Srpski](guide-sr.md) - [Sa Tagalog](guide-tl.md) - [Türkçe](guide-tr.md) - [简体中文](guide-zh_CN.md) - [繁體中文](guide-zh_tw.md) #### *Не намагайтесь одразу зрозуміти все*. Краще не зупиняйтесь і продовжуйте рухатись далі! ## Ком’юніті Наш канал в IRC - `#haskell-beginners` на серверах Freenode. Веб-інтерфейс для IRC можна знайти [тут](http://webchat.freenode.net/). Пов'язані з Haskell [поштові розсилки](https://wiki.haskell.org/Mailing_lists). Отримати допомогу українською можна в [Slack-чаті KyivHaskell](https://github.com/KyivHaskell/KyivHaskell#join-our-slack-channel) або [Gitter-чаті dou-ua/fp](https://gitter.im/dou-ua/fp). ### Норми та правила спільноти [Прочитайте допис Кріса Дона присвячений навчанню](http://chrisdone.com/posts/teaching) Будьте ввічливими та доброзичливими. Грубість та неввічливість відлякують людей і відбивають в них бажання співпрацювати. Легковажна і зверхня критика не сприймається адресатом і задовільняє лише того, хто критикує. Не описуйте речі як "легкі" або "тривіальні". Люди, що важко працюють над вдосконаленням своїх знань, через такі ремарки будуть почуватись жахливо. Зазвичай повільно навчаються ті, хто водночас є найбільш стараними учнями і це є радше приводом для радощів! Не треба удаваного здивування. Не зображуйте подив, коли хтось каже, що він чогось не знає. Люди знов таки будуть почуватись жахливо, а ви не досягнете майже нічого окрім різкості. Ніяких "Насправді". Хтось каже щось, що майже, але не цілковито, правильне, і тут ви кажете "насправді..." і додаєте малосуттєве виправлення. Особливо це дратує, коли виправлення має мало спільного з темою обговорення. Це не значить, що наша спільнота не орієнтована на пошук істини чи що ми не вважаємо, що точність важлива. Майже усі "насправді" призначені для самозвеличення, а не для пошуку істини. Намагайтесь не забігати поперед учня. Не треба періодично влізати із порадами якщо ви бачите, що людина працює над проблемою. Дайте їй шанс подолати проблему самотужки, а за потреби за порадою. Уникнення втручаннь є одним з найважливіших задумів #haskell-beginners. Ніяких -измів, навіть замаскованих. Расизм, сексизм, гомофобія, трансфобія та інші види упередженності у жодному разі не припускаються. Якщо ви не займаєтесь відвертим тролінгом, то на каналі ви можете отримати зауваження. Завжди зважайте на те, що канал створено для людей, які або самотужки вивчають Haskell або вчать програмуванню на ньому інших. # Встановлення Haskell ## Використовуйте Stack для початку роботи з Haskell Встановіть [Stack](https://haskellstack.org/) щоби встановити GHC та збирати свої проекти. Якщо ви не знаєте нічого про Stack та хотіли би отримати огляд — подивіться цей [відео туторіал](https://www.youtube.com/watch?v=sRonIB8ZStw). ## НЕ ВСТАНОВЛЮЙТЕ HASKELL PLATFORM Замість того, щоб слідувати інструкції на Haskell.org, використовуйте Stack. ## Чому не Haskell Platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # Як мені слід вивчати Haskell? Основна рекомендація - прочитати лекції та пройти всі вправи та домашні завдання версії Spring 13 курсу cis1940, потім пройти курс FP (посилання на обидва курси нижче). Все інше можна вважати додатковим матеріалом, який згадується для того, щоб ви знали, де шукати. ## Альтернативно... [@dmvianna](https://github.com/dmvianna) хотіла, щоби я вам передав, що це лише ресурси для безкоштовного вивчення. Якщо ви хочете купити книгу, ми сердешно рекомендуємо нашу власну [Haskell Book!](https://haskellbook.com/)! Ця книга замінює необхідність всіх інших ресурсів, перелічених тут. ## Курс cis1940 від Yorgey > *ПОЧНІТЬ З ЦЬОГО*, це головний рекомендований метод занурення в Haskell. Доступний [онлайн](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html). Курс [Брента Йорґі](https://byorgey.wordpress.com) (Brent Yorgey) - найкращій курс, який я знайшов на сьогодні. Особлива цінність цього курсу в тому, що він не тільки навчить вас писати базові речі на Haskell, але й допоможе зрозуміти комбінатори парсера. Не слід починати з cis1940 тільки в тому випадку, коли ви не програміст або програміст із маленьким досвідом. В цьому разі почніть з [цієї книги Томпсона](https://www.haskellcraft.com/craft3e/Home.html), після чого переходьте до cis1940. --- ## Курс FP > Цей курс рекомендовано до вивчання після закінчення курсу cis1940 Матеріали курсу доступні [на github](https://github.com/bitemyapp/fp-course). Цей курс посилить та збагатить ваш досвід через реалізацію абстракцій, які були введені в курсі cis1940. Такий практичний досвід є *критичним*, так як він надасть вам впевненості у повсякденному використанні Functor/Applicative/Monad/ін. у Haskell. Проходження cis1940, а після нього FP - головна рекомендація цієї інструкції. Саме так ми вчимо Haskell всіх бажаючих. --- ## Додаткові матеріали після курсів cis1940 та FP > Додатковий матеріал на більш складні теми Курс cs240h доступний [онлайн](http://www.scs.stanford.edu/14sp-cs240h/). Цей курс, створений Брайаном О'Салліваном(https://github.com/bos) за мотивами його викладацької діяльності в університеті Стенфорду. Щоб уявити хто це, зауважте такий факт: ледь не половина бібліотек, від яких залежить майже будь-яка програма на Haskell, містить його ім'я серед авторів. Після проходження курсу Йорґі особливо зверніть увагу на модулі присвячені фантомним типам, контролю потоку інформації, розширенням мови, сумісному виконанню, pipes та лінзам. --- # Ресурси, що розглядають конкретні теми Haskell На додаток пропонуються матеріали, присвячені поглибленному вивчанню більш складних тем, а також обговорюють інструменти розробки та текстові редактори. Ці матеріали не були випробувані у навчальних цілях так ретельно, як cis1940 та FP, але їх список можна передивитись # Конкретні питання по Haskell ### Що роблять синтаксичні конструкції `<-` / `do` / спискове включення? [Чудова стаття](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html) розглядає ці питання. ### Щоб зрозуміти списки та згортання списків (fold) - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### Щоб вивчити деякі відомі класи типів Матеріал, що дуже корисний для розуміння `Functor`, `Applicative`, `Monad`, `Monoid` та інших класів типів в цілому, а також трохи специіфчної для Haskell теорії категорій. - [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Розуміння базових повідомлень про помилки від Haskell - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Лінивість, строгість, стримана рекурсія - [Книга Марлоу](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) (Marlow) про паралелизм та сумісне виконання має одне з найкращих введень в лінивість та нормальні форми. Якщо матеріал з неї не буде засвоюватись, зверніться до інших джерел. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Питання на Stack Overflow '[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - Слайди з виступу [Johan Tibell](https://github.com/tibbe) на тему [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Маленька демонстрація ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Обов'язково прочитайте документацію та перегляньте реалізацію unsafeDupablePerformIO Коментар з обговорення в Reddit від `glaebhoerl` > Цікаве зауваження: GHC мусить приховувати представлення токену стану за абстрактним типом IO через те, що > токен стану завжди мусить використовуватись лінійно (не дублюватись або бути скинутим), але система типів не може примушувати до цього. > Інша Haskell-подібна мова під назвою Clean має систему унікальних типів (які подібні до лінійних типів і, можливо, інші в аспектах, які я не знаю), > і вони надають можливість прямої передачі World, маючи (не абстрактну) монаду IO тільки для зручності. Оригінал: > Interesting side note: GHC needs to hide the state token representation behind > an abstract IO type because the state token must always be used linearly (not > duplicated or dropped), but the type system can't enforce this. Clean, another > lazy Haskell-like language, has uniqueness types (which are like linear types > and possibly different in ways I'm not aware of), and they expose the > World-passing directly and provide a (non-abstract) IO monad only for > convenience. # Монади та їх трансформери > Не займатесь цим доки ви не розумієете класи типів, Monoid, Functor, Applicative! Самотужки реалізуйте бібліотечні монади (List, Maybe, Cont, Error, Reader, Writer, State) для того, щоб зрозуміти їх краще. Тоді, наприклад, напишіть монадний інтерпретатор невеликої мови виразів за допомогою [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf) (згадується також нижче, у розділі 'трансформери монад'). Написання декількох інтерпретаторів простою зміною монад для зміни семантики може надати додаткового розуміння про те, що відбувається. Також заново реалізуйте `Control.Monad`. Функції накшталт `mapM` чи `sequence` є чудовою можливістю набути практики з написання узагаленного монадічного коду. У якості путівника можна також використати курс FP, частиною якого також є написання власної реалізації Applicative. Автори: - Коментар на Reddit від htmltyp та Crandom [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Коментар на Reddit від jozefg [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Трансформери монад - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](http://catamorph.de/documents/Transformers.pdf). # Тестування, тести, специфікації, тестування властивостей та генеративне - [Фантастичний посібник](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) від Kazu Yamamoto. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Гарна маленька бібліотека, яка допомогає зрозуміти, як загалом працює потоковий IO. Це знання можна відобразити на бібліотеки типу Pipes та Conduit. # Парсинг у Haskell - [Посібник](https://github.com/JakeWheat/intro_to_parsing) з комбінаторів парсеру із використанням Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Парсинг та генерація JSON Aeson - стандартне рішення для парсингу [JSON](https://json.org) в Haskell. Цей пакет доступний на [hackage](https://hackage.haskell.org/package/aeson) та [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson tutorial](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Структури даних та алгоритми для роботи з графами - [Пакет fgl](https://hackage.haskell.org/package/fgl), зокрема чисто функціональні [алгоритми найкоротшого шляху](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph source from Containers package](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - [Пакет graphs](https://hackage.haskell.org/package/graphs). - [Питання про PHOAS на Stack Overflow](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS for free](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Середовище розробки ## Emacs - [Посібник від Alejandro Serras](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [My dotfiles](https://github.com/bitemyapp/dotfiles/) - [Chris Done's emacs config](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim page on haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Робота із Cabal ## Принципи роботи з Cabal До того, як з'явились так звані сендбокси, користувачі Haskell стикались з проблемою, відомою як Cabal Hell. Встановлення пакетів поза сендбоксом призведе до реєстрації його у базі package-db, що є глобальною для користувача, і зазвичай це не дуже гарна ідея. Виключенням є лише найбазовіші пакети накшталт Cabal, alex, happy. Нічого іншого не мусить встановлюватись у package-db глобальний для системи або користувача окрім випадків, коли ви дійсно знаєте, що робите. Поради як запобігти потраплянню в Cabal Hell, можна прочитати [тут](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). Для того, щоб поекспериментувати із пакетом, або розпочати новий проект, почніть зі створення сендбоксу у новій директорії: `cabal sandbox init`. Якщо коротко: - Завжди використовуйте сендбокси для інсталяції нових пакетів, збирання нових або існуючих проектів, або ж для експериментів. - Для запуску інтерпретатору GHC у контексті проекту, завжди використовуйте `cabal repl`. Рекомендований тут підхід, що базується на використанні сендбоксів, призначений допомогти обійти проблеми із залежностями, але він не сумісний із тим, як Haskell Platform надає готові пакунки. Якщо ви ще тільки вивчаєте Haskell і не розумієте, як працють ghc-pkg and Cabal, *уникайте platform* і замість того використовуйте підхід, що описано раніше в цьому посібнику. ## Stackage Усі користувачі, в яких є проблеми з білдами (зазвичай це користувачі Yesod), мають можливість обміркувати використання Stackage. - Непоганий огляд Stackage можна знайти [тут](https://www.fpcomplete.com/blog/2014/05/stackage-server). Автор вважає, що Stackage, зазвичай, більш корисний, ніж `cabal freeze`. # Hoogle and Haddock ## Шукайте код за сигнатурою типів [Пошуковий сервіс Hoogle](http://www.haskell.org/hoogle/) вміє шукати за типом. Наприклад, подивіться на результати пошуку за виразом `(a -> b) -> [a] -> [b]` [тут](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Ще одне дзеркало [на fpcomplete](https://www.fpcomplete.com/hoogle). Ще є [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (який для пошуку за замовченням використовує увесь зміст hackage). ## Налаштування власної локальної копії Hoogle [Описано тут](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Hackage documentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Зауваження: обидві статті *трошки застаріли*: наприклад, зараз Hackage також показує новесеньку інформацію стосовно статусу білда і документації. ## Що дійсно треба знати Для того, щоб haddocks містив документацію і з пакунків, які стосуються вашого проекту, треба додати `documentation: True` до вашого `~/.cabal/config`. Якщо було використане значення за замовчуванням (`False`) або `False` було встановлене вручну, то перед генерацією haddocks необхідно буде видалити всі ваші пакунки і заново переінсталювати їх. Треба пам'ятати ще одну річ: через те, що Cabal, *а не ви*, інтерпретує параметр `$pkg`, параметри `html-location` та `content-location` *мусять бути записані у одинарних лапках* і введені в командний інтерпретатор або записані у скрипті інтерпретатора. Вони не будуть працювати у Makefile через те, що вони будуть інтерпретовані як змінні Make! ```bash #! /usr/bin/env sh # Цю команду можна записати в один рядок, але тоді приберіть слеші cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Якщо ви є великим шанувальником [TravisCI](https://travis-ci.org), тоді *дуже* рекомендується подивитись на [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) як на базовий приклад `travis.yml` для ваших Haskell-проектів. # Frontend/JavaScript Тут в нас є просто безліч різноманітних варіантів. Ось три базові рекомендації: * [Haste](http://haste-lang.org/) компілятор із Haskell в Javascript - [Компілятор](https://github.com/valderman/haste-compiler) на github. - Чудова [демка](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) використання Haste із реальним проектом. * [GHCJS](https://github.com/ghcjs/ghcjs) - [Введення у GHCJS](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Доволі популярний вибір серед прибічників Haskell, хоча, на відміну від Haste та GHCJS, це не зовсім Haskell. - Написано на Haskell під впливом Haskell - Спробувати PureScript прямо у браузері можна [тут](http://try.purescript.org/) - [Чудовий посібник](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) про те, як почати працювати з PureScript ## Яку мову використовувати для фронтенду І GHCJS, і Haste є повноцінними реалізаціями Haskell. Під GHCJS будуть працювати більше Haskell проектів, ніж із Haste, але це не дуже впливає на розробку фронтенд-проектів. Purescript - це зовсім не Haskell і тому використовувати код із бекенду напряму не вийде. GHCJS має найбільший розмір допоміжних бібліотек, необхідних для його роботи, який сягає 100Кб (luite працює над цією проблемою). Haste та PureScript більш-менш однакові. Інтеграція із інструментарем JS найкраща в PureScript (використовується gulp/grunt/bower), в той час як GHCJS та Haste краще працює із інструментами Haskell (Cabal). Усі три - чудовий вибір і підходять для більшості фронтендових проектів. # Для більш повного розуміння лінивості NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## Дослідницькі папери про ліниве лямбда-числення - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Паралелізм/конкаренсі - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929). Ця книга за авторством Саймона Мерлоу (Simon Marlow) є, мабуть, однією із найкращих книг про паралелізм та конкаренсі - Ґрунтовний [посібник](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) стосовно тестування та інкрементальної розробки багатопотокових програм на Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses та Prisms Після того, як ви набудете певності у роботі із Haskell, поставьтесь серйозно до вивчення Lenses та Prisms, навіть якщо ви просто "користувач". Для того, щоб вони стали вам у нагоді, не треба розуміти базові для них категорії. Люди з легкістю переоцінюють складність використання Lens. Будь-хто із достатнім розумінням Functor/Foldable/Traversable (або навіть лише Functor) може використати лінзи та призми для того, щоб зробити своє життя трішечки краще. Якщо коли небудь ви писали щось типу `(fmap . fmap)`, ви подумки використовували лінзи. Ці дві статті є рекомендованим введенням в тему: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Для подальшої інформації звертайтесь сюди: [Lens package on hackage](http://hackage.haskell.org/package/lens). # Схеми рекурсії Деякі божевільні \*-morphism слова, які ви зустрічали, насправді говорять про рекурсію. Зауважте: перед тим, як переходити до цього матеріалу, треба розуміти, як реалізувати foldr для списків і хочаб ще однієї структури даних, наприклад для дерев (fold - це катаморфізм). Розуміння реалізації unfold (анаморфізм) для тих же структур ще більше полегшить вивчення теми. Цей матеріал пов'язує між собою traversable та foldable. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Цікава демонстрація того, що гілеоморфізм є композицією катаморфізму та анаморфізму. - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - Блискучий практичний досвід - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core та оптимізація швидкості виконання - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Типи та теорія категорій > *НЕ ПОТРІБНА* для того, щоб просто писати на Haskell. Просто для тих, хто цікавиться. Якщо ви маєте час та натхнення набути розуміння типів та теорії категорій: - [Catster's Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) та [Catster's Guide 2](http://byorgey.wordpress.com/catsters-guide-2/) - [Haskell wikibook](http://en.wikibooks.org/wiki/Haskell/Category_theory) містить непогані діаграми - Сторінка [Category Theory](http://www.haskell.org/haskellwiki/Category_theory) у haskellwiki також містить чудові посилання на інші ресурси - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), містить також і практичні приклади. - Список [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) за авторством Пірса. ## Книги - [Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) Рекомендація Кметта (Kmett) - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) та [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Стандартні підручники з теорії категорій. - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) - найкраще введення у теорію типів із фокусом на мовах програмування. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Інші веселі теми ## Параметричність, ad-hoc та параметричний поліморфізм, вільні теореми - [Parametricity](tony_parametricity.pdf). - [TeX оригінали](https://github.com/tonymorris/parametricity/) вищевказанної доповіді - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial та Final, DSL, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) менш релевантна, але все одно цікава стаття. ## Комонади - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, a sequence of three articles by Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (обчислення) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Залежна типізація - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html). - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # Статична лінковка бінарників - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ## Діалоги > Діалоги із IRC знаходяться [в цьому документі](dialogues.md). Це дуже важлива та корисна інформація. Зазирніть туди щоб заглибитись у різноманітні теми. ================================================ FILE: guide-zh_CN.md ================================================ # 前言 这是根据帮助别人的经验总结而来的一条 Haskell 学习路线,其中列出了 [Haskell 书](https://haskellbook.com/)的作者之一所推荐的一系列学习资料。 #### _如果遇到不懂的地方也不要紧张。继续读下去!_ ## 社群 IRC 频道:Freenode 上的 `#haskell-beginners`。 IRC web 版[客户端](http://webchat.freenode.net/)。 Haskell [邮件群组](https://wiki.haskell.org/Mailing_lists)。 ### 社群参与原则 阅读我们的[社群参与原则](coc.md),了解在 IRC 频道应遵守的原则。变相的攻讦行为将会被警告。请注意,这个频道是专为学习和教授 Haskell 的人准备的。 # 安装 Haskell ## 通过 Stack 使用 Haskell 获取 [Stack](https://haskellstack.org) 来安装 GHC 并构建你的项目。 如果你对 Stack 一无所知,又想了解一下,可以看看这个[全面的 Stack 视频教程](https://www.youtube.com/watch?v=sRonIB8ZStw)。 ## 还有,不要安装 Haskell Platform 直接使用 Stack,而不要遵循 Haskell.org 里面的说明。 ### 为什么不使用 platform? https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html # 我该如何学习 Haskell? 推荐的核心是阅读 cis1940 课程(2013 年春季学期版)的讲解并完成所有习题和作业,然后是 FP 课程。下方列出了两门课的链接。其他的所有内容都可以视为选学内容,我们就在这里提一下是为了让你知道该到哪里找到它们。 ## Haskell 编程:从第一原理开始 [@dmvianna](https://github.com/dmvianna) 让我告诉你,下面列出的都只是*免费*的推荐资料。如果你愿意看书,衷心推荐我们自己写的 [Haskell 书](https://haskellbook.com/)!如果你因为某些原因买不起这本书,请使用[支持页面](https://haskellbook.com/support.html)里的联系方式发邮件给我们。 ### Haskell Book 书包含了这里列出的全部基础资料(包含的内容) ## Yorgey 的 cis1940 课程 > 如果/你不打算买那本 Haskell 书,那就*先学习*本课程,它是最好的免费 Haskell 入门介绍。 [在线](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html)获取。 [Brent Yorgey](https://byorgey.wordpress.com) 的课程是迄今为止我所发现的最好的课程。 这门课程非常有价值,因为它不仅会教你编写基本的 Haskell,而且还会帮助你了解语法分析组合子。 只有当你不是程序员,或者是个缺乏经验的程序员时,你才不应该从 cis1940 开始学。 如果你真的是这样,请从[Thompson 的这本书](https://www.haskellcraft.com/craft3e/Home.html)开始学并过渡到 cis1940。 --- ## 函数式编程课程 > 我们推荐你在完成 Yorgey 的 cis1940 课程之后再学习这门课。 在 GitHub [这里](https://github.com/bitemyapp/fp-course)获取。 这门课会让你直接体验用代码实现 cis1940 中介绍过的各种抽象并加深你对它们的理解。这样的练习对于让你熟悉 Haskell 中 Functor/Applicative/Monad 等等概念的日常使用至关重要。先学 cis1940,然后学 FP,是我这篇指南的核心,也是我教大家 Haskell 的方式。 --- ## cis1940 和 FP 课程之后的补充课程 > 这门课提供了更多中级材料 cs240h 可从线上获取 - [2014 年春季学期版](http://www.scs.stanford.edu/14sp-cs240h/) - [2016 年冬季学期版](http://www.scs.stanford.edu/16wi-cs240h/) 这是 [Bryan O'Sullivan](https://github.com/bos) 在斯坦福大学教的在线课程。如果你不知道他是谁,你可以去瞟一眼所有 Haskell 应用程序都总会需要的那些库,其中一半的库上都写着他的名字。如果你已经学过 Yorgey 的课程的话,要特别注意讲解幽灵类型、信息流控制、语言扩展、并发、管道和透镜的章节。 --- # 补充资料 这些资料不像 cis1940 和 FP 课程那样经过了学习者的共同把关和评测,它们的链接都在[主题清单](/specific_topics.md)里,方便你知道从哪里开始。这里面涉及中高级的概念和课题,比如工具和文本编辑器。 ## 译著 补充资料部分的旧版中译可从[这里](https://github.com/bitemyapp/learnhaskell/blob/213dcb9decdce7f6f472247f0d4b82447e015f1d/guide-zh_CN.md#---do--list-comprehension%E7%AE%80%E4%BE%BF%E8%AF%AD%E6%B3%95%E5%88%B0%E5%BA%95%E6%98%AF%E4%BB%80%E4%B9%88)获得。 ## 对话记录 > 存放在[这个仓库](dialogues.md)里。 这些对话真的相当重要而会对你很有帮助,想深入了解各种主题请看这里。 ================================================ FILE: guide-zh_tw.md ================================================ # 前言 這是我推薦的學習Haskell之路。 #### 請切記:*別在不懂的地方打轉,先繼續讀下去!* ## 社群 IRC頻道是Freenode上的`#haskell-beginners`。 IRC web版用戶端可[在這裡取得](http://webchat.freenode.net/)。 Haskell[郵件群組](https://wiki.haskell.org/Mailing_lists)。 ### 社群參與原則 請參考Chris Done所撰:[Teaching](http://chrisdone.com/posts/teaching)。 請友善待人,尖酸苛薄只會把人嚇跑、令人不願再參與而已。 低劣的批評只讓你自己痛快,對聽者毫無幫助。 別說『這很簡單』、『這沒什麼』。這會讓人覺得要花這麼多功夫來弄懂是因為自不如人,學得慢的人通常是學得最全面的人,這值得稱讚! 當別人承認他不知道的時候,不要故作驚訝。這會讓他難過,而你除了表現得好像很行,什麼也沒得到。 不要說『其實...這樣才對...』(well, actually...)。當有人說了什麼『幾乎正確』的話,而你說些『其實...這樣才對』來做些枝微末節的修正,這很惱人,尤其這常常跟整個討論根本八竿子打不著。我並不是在說人們不在乎精確,只是像這樣的發言通常是作秀成分居多,而非為了追尋真實。 --- 以上部分內容來自[the Recurse Center手冊](https://www.recurse.com/manual)。感謝他們願意公開分享! # 什麼是Haskell、GHC和Cabal? Haskell的規格可在下面這篇報告找到,此報告最新版本為2010版: [onlinereport](http://www.haskell.org/onlinereport/haskell2010/) ## GHC [GHC](http://www.haskell.org/ghc/)是Haskell語言的主流工具選擇。它包含編譯器、直譯器、套件管理,與其他輔助工具。 ## Cabal [Cabal](https://www.haskell.org/cabal/download.html)可用來做專案管理與套件相依性解析。 這會是你用來安裝專案、套件的主要工具,其常見的做法是安裝到專屬的沙箱(cabal sandbox)中。 Cabal相當於Ruby Bundler、Python pip、Node NPM、Maven等等。你可以用GHC來打包套件,Cabal則可用來選擇你想要的版本安裝。 # 環境設定 ## Ubuntu [這個PPA](http://launchpad.net/~hvr/+archive/ghc)很棒,我在我所有的Linux環境與建置用機器上都靠它。 詳細設定步驟如下: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.20 ghc-7.8.4 happy-1.19.4 alex-3.1.3 ``` 接著,把以下路徑加入你的`$PATH`環境變數中(bash\_profile, zshrc, bashrc, etc): ``` ~/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.8.4/bin:/opt/happy/1.19.4/bin:/opt/alex/3.1.3/bin ``` *註:* 你不妨把`.cabal-sandbox/bin`加到你的路徑中。如此一來,只要你使用沙箱(cabal sandbox)開發,並且 留在專案的工作路徑中,你就可以在命令列中輕易取用你正在開發的二進位檔。 ## Debian ### 使用Ubuntu PPA 如果不打算使用官方提供的穩定版本,你可以用上面提過和Ubuntu一樣的流程,但會需要在下面這個命令後: `sudo add-apt-repository -y ppa:hvr/ghc` 加上: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` 其他的Debian版本,只需將`jessie`都換成你的版本名即可。 如果`/etc/apt/sources.list.d/hvr-ghc-jessie.list`不存在,那麼`/etc/apt/sources.list`應該會有: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main 把上列`jessie`換成`trusty`即可。 ### 自行編譯 請參照這篇為Mac OSX所撰的指南: 請注意: - 根據你個人的工作環境,設定ghc時指定目錄前綴(prefix) - 不要直接下載`cabal-install`的二進位檔,請下載源碼並執行其`bootstrap.sh`腳本。 ## Fedora 21 從非官方套件庫安裝Haskell 7.8.4 (Fedora 22以上已經有官方版本): ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` 根據[petersen/ghc-7.8.4 copr page](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/),此版本的ghc 無法與Fedora/EPEL ghc並存。 ## Arch Linux 從官方套件庫安裝: ```bash $ sudo pacman -S cabal-install ghc happy alex haskell-haddock-library ``` ## Gentoo 你可以透過Portage來分別安裝Haskell Platform的各個組件。如果你使用`ACCEPT_KEYWORDS=arch`,而非`ACCEPT_KETWORDS=~arch`, Portage會弄個老舊的Haskell給你。因此,舉凡用了`ACCEPT_KEYWORDS=arch`,請把下面這幾行加進去: dev-haskell/cabal-install ~arch dev-lang/ghc ~arch 接著請執行: ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo會留一個『穩定』(換言之:老舊)的`cabal-install`在Portage的套件樹中,你可以利用這個`cabal-install`來安裝 新版的`cabal-install`。請注意,以下反斜線是必須的: ```bash $ \cabal update # The backslashes $ \cabal install cabal-install # are intentional ``` 如此一來,你便透過Protage在系統中安裝了cabal,又在你的個人環境中安裝了最新的`cabal-install`。 下一步是確定每次你在終端機執行`cabal`時,你的shell都是執行你個人環境中的最新版本: ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` 不知道你的shell是哪一個?那你很可能用的是Bash。如果你用的是Bash,你需要編輯`~/.bashrc`。 如果是Z-shell,則是`~/.zshrc`,可用以下面命令來查詢: ```bash echo $SHELL | xargs basename ``` 例如我用的是zsh,所以上列命令會輸出`zsh`。 當以上都完成,請再另外安裝兩個工具:`alex`和`happy`: ```bash $ cabal install alex happy ``` 恭喜!你有了一個正常運作的Haskell! ## Mac OS X ### 10.9 請安裝[GHC for Mac OS X](http://ghcformacosx.github.io/),它包含了GHC與Cabal。安裝完成後, 它會指示你如何將GHC與Cabal加入你的系統路徑。 ### 10.6-10.8 請下載這個[tarball](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2), 並安裝其包含的二進位版。 ## Windows - [windows minimal GHC installer](http://neilmitchell.blogspot.com/2014/12/beta-testing-windows-minimal-ghc.html) 它可以用來編譯`network`等套件,雖然嚴格說它還在beta,但應該足夠讓任何讀這篇導覽的人使用。 別忘了,要用系統管理者的身份來安裝,因為它需要新增到Program Files的權限。 ## 其他Linux使用者 下載cabal與ghc的最新版二進位檔。 - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). # 主要學習課程 ## Yorgey's cis1940課程 > *請先透過這門課學習*,這是我最推薦入門Haskell的課。 此課程的教材可於[線上取得](https://www.seas.upenn.edu/~cis1940/spring13/lectures.html)。 [Brent Yorgey](https://byorgey.wordpress.com)的課是我目前所知最好的。它之所以好,因為 它不只教你些基礎知識,還教你parser combinators。 如果你不是個程式設計師,或缺乏經驗,那麼這門課可能沒這麼適合。建議你從 [Thompson的這本書](https://www.haskellcraft.com/craft3e/Home.html)開始,然後再轉到cis1940。 --- ## FP課程 > 在你完成上述Yorgey的cis1940後,我推薦繼續挑戰此課程。 這門課發佈在[github上](https://github.com/bitemyapp/fp-course)。 透過實作cis1940中所介紹過的種種抽象表述,你會有更深入的了解。這樣的練習對於 熟悉Haskell中每天都會面對的Functor/Applicative/Monad等等至關重要。 先做cis1940,緊接著FP,是這整篇Haskell學習導覽的核心,也是我教每個人Haskell的方式。 --- ## 補充課程 cs240h > 提供更多中階以上議題的教材 [線上教材](http://www.scs.stanford.edu/14sp-cs240h/) 這是[Bryan O'Sullivan](https://github.com/bos)在Stanford所教課程的線上版。 如果你不知道他是誰,去翻翻Haskell的函式庫吧!幾乎一半以上常用的套件都有他的名字。 特別是phantom types、information flow control、language extensions、concurrency、pipes和lenses。 --- ### `<-` / `do` / list comprehension簡便語法到底是什麼? [很棒的解釋](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html)。 ### 了解list和fold - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### 學習常用的typeclasses 對瞭解`Functor`、`Applicative`、`Monad`、`Monoid`和其他typeclasses很有幫助,而且還有 些針對Haskell的範疇論(category theory)的解釋: - [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### 了解基本的Haskell錯誤訊息 - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Laziness, strictness, guarded recursion - [Marlow關於平行與同步的書](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html)中,關於laziness與normal form的介紹 是我所看過最好的。如果沒有立即理解,不妨搭配以下補充材料。 - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - SO上的討論串'[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - [Johan Tibell](https://github.com/tibbe)'在[reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness)這個演講的投影片 ## 演示 ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) 請讀unsafeDupablePerformIO的文件和實作筆記。 `glaebhoerl`在Reddit討論串的留言: > 有趣的補充筆記: GHC需要將state token representation隱藏在抽象的IO型別後面, > 因為state token必須線性地使用,不能複製或丟棄,但型別系統無法強制這件事。 > 某個乾淨、lazy、類似Haskell的語言的型別有uniqueness特性(類似linear type,但可能有些 > 我沒意識到的細微差別),為了方便,它直接暴露World-passing並提供非抽象的IO monad。 # Monads and monad transformers > 在你了解typeclasses、Monoid、Functor和Applicative之前,請不要做下列練習! 嘗試自行實作標準函式庫中的monads(List、Maybe、Cont、Error、Reader、Writer、State),可以讓你 更了解它們。再來,不妨嘗試用下述技術實作一個小型expression language的monadic直譯器: [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf)(在下列monad transformer章節亦有提及) 透過用不同的monad改變語意,從而產生不同的直譯器,help convey what's going on。 再來,實作`Control.Monad`中的函數,例如:`mapM`或`sequence`是個練習撰寫generic monadic code的好機會。 前面提到過的FP課程也可以用來當這個過程的指南,它也包括了如何撰寫你自己的Applicative。 Credits: - Reddit上htmltyp和Crandom的[留言](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6)。 - Reddit上jozefg[的留言](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg)。 ## Monad transformers - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md)。 - [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf) # Testing, tests, specs, generative/property testing - Kazu Yamamoto的[這篇教學](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md)堪稱典範! - [Simple-Conduit](https://github.com/jwiegley/simple-conduit):這個簡單的函式庫對於學習IO串流如何工作很有幫助, 所學亦可應用在其他函式庫,例如Pipes和Conduit。 # Parsing in Haskell - Parser combinator [tutorial](https://github.com/JakeWheat/intro_to_parsing) for Haskell using Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Parsing與產生JSON Aeson是Haskell標準的[JSON](https://json.org)parsing解決方案。你可以從[hackage](https://hackage.haskell.org/package/aeson)或[github](https://github.com/bos/aeson)取得。 - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson教學](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # 圖學演算法與資料結構 - [fgl套件](https://hackage.haskell.org/package/fgl)。純函數式的最短路徑[演算法](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html)值得一看。 - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Containers套件中的Data.Graph源碼](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - [graphs套件](https://hackage.haskell.org/package/graphs). - [SO關於PHOAS的討論串](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [免費的PHOAS](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # 開發環境 ## Emacs - [Alejandro Serras's tutorial](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [My dotfiles](https://github.com/bitemyapp/dotfiles/) - [Chris Done's emacs config](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim page on haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [A vim+haskell workflow](http://www.stephendiehl.com/posts/vim_haskell.html) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Cabal常見問答 ## 一篇超讚的常見問答 不但對各種主題都有很好的導覽,也包含了Cabal的一些重要基礎。 - [What I wish I knew when learning Haskell](http://dev.stephendiehl.com/hask/) ## Cabal導覽 在引入沙箱(sandbox)前,Cabal地獄(Cabal Hell)對所有Haskell使用者來說都是一大問題。 在沙箱外安裝的套件會直接裝在你的用戶套件資料庫(user pacakge-db)中。除非是常用的基礎套件, 例如Cabal、alex、happy等,這絕不是個好方法。除非你很清楚你自己在做什麼,任何套件都不該 安裝在用戶資料褲或全域資料庫(global package-db)。 這裏有些如何避免Cabal地獄的[最佳指南](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html)。 如果要實驗新套件,或是起始新專案,在一個新目錄中執行`cabal sandbox init`。 簡言之: - 無論是安裝新套件、建置新舊專案、做任何實驗,請用沙箱。 - 用`cabal repl`來啟動project-scoped ghci實體。 我所建議這種以沙箱為基礎的方式,應該可以避免套件相依性的問題。但這與Haskell Platform提供 預先編譯套件的方法不相容。如果你還在學習Haskell,而且不太了解ghc-pkg和Cabal如何運作, *不要用Haskell Platform*,改用前面所提的安裝方式。 ## Stackage 如果你面臨一些建置上的問題(特別是Yesod),不妨考慮用Stackage: - [Stackage是什麼](https://www.fpcomplete.com/blog/2014/05/stackage-server) 據作者所言,Stackage通常比`cabal freeze`更實用。 # Hoogle與Haddock ## 依型別表述搜尋源碼 [Hoogle搜尋引擎](http://www.haskell.org/hoogle/)可依型別搜尋。 比方說,請看以下搜尋`(a -> b) -> [a] -> [b]`的結果: [搜尋結果](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). fpcomplete所管理的[在此](https://www.fpcomplete.com/hoogle)。 另外[Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html)預設開啟了對所有hackage的搜尋。 ## 設定你自己本地端的Hoogle 詳細方法請看[這篇文章](https://gist.github.com/bitemyapp/3e6a015760775e0679bf)。 ## Haddock 1. 修正你的hackage文件 [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. Hackage文件第二版 [Hackage documentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) 請注意,以上這些文章都*有些過期*,例如:現在Hacakge已支援shiny new info with documentation info and build status. ## 真正重要的事 為了讓haddocks含入相關套件的文件,你必須在`~/.cabal/config`設立`ducumentation: True`。如果它被設為`False`,或間接被default(`False`)關閉,你會需要刪除並重新安裝所有套件,再產生haddocks。 請記住,因為`$pkg`參數會被cabal內插,`html-location`和`content-location`參數*必須以單引號括入*,再插入shell命令或包含在shell腳本中。在Makefile中是不行的,因為它會被當作Make的變數! ```bash #! /usr/bin/env sh # 如果把反斜線去掉,你可以把它寫成一行 cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI 如果你跟我一樣,是[TravisCI](https://travis-ci.org)的超級粉絲,那我*強力建議*你參考[multi-ghc-travis](https://github.com/hvr/multi-ghc-travis)為你的Haskell專案的`travis.yml`設定檔做基礎。 # 前端/JavaScript 我們的選擇多得驚人!我個人推薦三種: * [Haste](http://haste-lang.org/) Haskell至JavaScript的編譯器。a Haskell to JavaScript compiler - [Github](https://github.com/valderman/haste-compiler)上的編譯器源碼 - 範例專案的[精彩展示](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) * [GHCJS](https://github.com/ghcjs/ghcjs) - GHCJS簡介 [GHCJS Introduction](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - 用Haskell搭配ghcjs撰寫Atom插件 [Writing Atom plugins in Haskell using ghcjs](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - 不像Haste或GHCJS般是純Haskell,但是Haskller們的熱門選擇 - 以Haskell實作,亦受Haskell啟發 - 在瀏覽器上[試試](http://try.purescript.org/) - [起步導覽](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## 我用哪一種前端語言? GHCJS和Haste都是純Haskell,GHCJS比Haste能和更多的Haskell套件相容,但這不會影響大多數的前端專案。PureScript並非Haskell,因此無法直接和你的後端分享源碼。 GHCJS的執行期payload是最大的,大約100kb (luite正在研究如何解決此問題),Haste則和PureScript差不多。 PureScript有最好的JS工具鏈整合(用gulp/grunt/bower),GHCJS和Haste則與Haskell工具鏈整合較佳(例如Cabal)。 以上三者都是極佳選擇,大多數的前端專案都適用。 # 想要更充分了解laziness、NF、WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## 關於lazy lambda calculus的研究論文 - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # 平行/並行(Parallelism/Concurrency) - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929)。在我所讀過的文獻中,Simon Marlow所撰的這本書是此主題的佼佼者。 - [這篇教學](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application)帶領你一步步學習如何用Haskell測試、漸進開發多緒應用程式。 - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses and Prisms 在你習慣Haskell後,我強烈建議你學習Lenses與Prisms。你不必了解底層的原理,只要當一個使用者,就很受用。 大家普遍誤會Lens是個很難用的東西,其實任何一個了解Functor/Foldable/Traversable,甚至只知道Functor的人,都可以運用Lenses與Prisms來讓他們的開發生涯更快樂。 如果你曾經做過:`(fmap . fmap)`,你其實已經有Lense的思維了。 我推薦以下兩篇教學: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) 詳細資料請看這裡:[Lens package on hackage](http://hackage.haskell.org/package/lens). # 遞迴範式 (Recursion Schemes) 你一定聽過些瘋狂的『\*-morphism』,他們其實只是遞迴。在嘗試搞懂前,你應該要先知道如何實作list至少一種其他資料結構的foldr,例如tree (folds叫做catamorphisms)。再進一步瞭解如何在以上資料結構實作unfold (anamorphism)會讓整體知識完善些。 以下資料與traversable和foldable的概念相合。 - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Good demonstration of how hylomorphism is the composition of cata and ana. - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - This field guide is excellent. - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC核心與效能調校 - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # 型別(Type)與範疇論(Category Theory) > 寫Haskell*不用學*,僅供有興趣的人參考! 如果你想開始學習型別與範疇論: - [Catster's Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) and [Catster's Guide 2](http://byorgey.wordpress.com/catsters-guide-2/) - [haskell wikibook](http://en.wikibooks.org/wiki/Haskell/Category_theory) 有不錯的圖解。 - Haskellwiki上的[Category Theory](http://www.haskell.org/haskellwiki/Category_theory)也有不錯的參考資料。 - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html),有實例。 - Pierce的[Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml)列表。 ## 書籍 - Kmett推薦:[Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do)和 [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038)。範疇學的標準教科書。 - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf)是我讀過以程式語言角度切入的最佳介紹。 - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). ## Stephen俏皮的"How to get to monad"文章 - [Adjunctions](http://www.stephendiehl.com/posts/adjunctions.html). - [Monads](http://www.stephendiehl.com/posts/monads.html). # 其他有趣的主題 ## Parametricity, ad-hoc vs. parametric polymorphism, free theorems - [Parametricity](tony_parametricity.pdf). - [TeX sources](https://github.com/tonymorris/parametricity/)上述演講的TeX源。 - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial與Final、DSLs、與Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/)較無相關,但非常有趣。 ## Comonads - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, Edward Kmett的系列文章 * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (computation) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Dependent typing - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) squint hard. - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # 靜態連結二元檔Statically linking binaries - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) # 補充資料 > 有部分已在本文提及 - [Essential Haskell Reading List](http://www.stephendiehl.com/posts/essential_haskell.html) ## 對話記錄 > 在[本儲存庫中](dialogues.md)。 裡面有些非常重要而有幫助的資訊,可協助你深入了解許多不同的議題。 ================================================ FILE: install.md ================================================ # These instructions are deprecated We now recommend you use [Stack](https://haskellstack.org) instead, but the instructions are preserved here for those that might want a minimal install. # What are Haskell, GHC, and Cabal? Haskell is a programming language as laid out in the reports, most recent one being in 2010. The report is available as the [onlinereport](http://www.haskell.org/onlinereport/haskell2010/). ## GHC [GHC](http://www.haskell.org/ghc/) is the most popular way to work in the Haskell language. It includes a compiler, REPL (interpreter), package management, and other things besides. ## Cabal [Cabal](https://www.haskell.org/cabal/download.html) does project management and dependency resolution. It's how you'll install projects, typically into their own sandbox. Cabal is equivalent to Ruby's Bundler, Python's pip, Node's NPM, Maven, etc. GHC manages packaging itself, Cabal chooses what versions to install. # Installing GHC & Cabal ## Ubuntu [This PPA](http://launchpad.net/~hvr/+archive/ghc) is excellent and is what I use on all my Linux dev and build machines. Specifically: ```bash $ sudo apt-get update $ sudo apt-get install python-software-properties # v12.04 and below $ sudo apt-get install software-properties-common # v12.10 and above $ sudo add-apt-repository -y ppa:hvr/ghc $ sudo apt-get update $ sudo apt-get install cabal-install-1.24 ghc-7.10.3 happy-1.19.5 alex-3.1.4 ``` Then prepend the following to your `$PATH` (bash\_profile, zshrc, bashrc, etc): ``` export PATH=~/.cabal/bin:/opt/cabal/1.24/bin:/opt/ghc/7.10.3/bin:/opt/happy/1.19.5/bin:/opt/alex/3.1.4/bin:$PATH ``` *Optional:* You could also add `.cabal-sandbox/bin` to your path. Code that you are actively developing will be available to you from the command line. This only works when your current working directory is a cabal sandbox. ## Debian ### Using Ubuntu PPA If you're not using stable, you can follow the same steps as Ubuntu, but will have to execute an additional command. Immediately after `sudo add-apt-repository -y ppa:hvr/ghc` is executed run: ```bash $ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list ``` For other Debian versions, just replace all occurences of `jessie` with your version name in the command above. If, for some reason, the file `/etc/apt/sources.list.d/hvr-ghc-jessie.list` does not exist, then `/etc/apt/sources.list` should contain a line like this: deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main Replace `jessie` with `trusty` in this line. ### Manual compilation You can follow [this](http://www.davesquared.net/2014/05/platformless-haskell.html) guide written for Mac OS X: Notes: - Set your prefix accordingly when configuring ghc. - Instead of grabbing the `cabal-install` binary, grab the source and then run `bootstrap.sh` script. ## Fedora 21 To install Haskell 7.8.4 from the unofficial repo (Fedora 22+ will include it in the official one): ```bash $ sudo yum-config-manager --add-repo \ > https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo $ sudo yum install ghc cabal-install ``` As stated in [petersen/ghc-7.8.4 copr page](https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/) this ghc cannot be installed in parallel with Fedora/EPEL ghc. ## Arch Linux To install Haskell from the official repos on Arch Linux, run ```bash $ sudo pacman -S cabal-install ghc happy alex haddock ``` ## Gentoo On Gentoo, you can install the individual components of the Haskell Platform through Portage. If you use `ACCEPT_KEYWORDS=arch` (as opposed to `ACCEPT_KEYWORDS=~arch`), Portage will install ancient versions of the various Haskell things. With that in mind, iff you use `ACCEPT_KEYWORDS=arch`, add the following to `/etc/portage/package.accept_keywords`. dev-haskell/cabal-install ~arch dev-lang/ghc ~arch Once that is done, ```bash $ emerge -jav dev-lang/ghc dev-haskell/cabal-install ``` Gentoo keeps a "stable" (read: old) version of `cabal-install` in the Portage tree, so you'll want to use `cabal-install` to install the more recent version. Note that the backslashes are intentional. ```bash $ \cabal update # The backslashes $ \cabal install cabal-install # are intentional ``` You have now installed cabal on a global scale with portage, and locally in your home directory with `cabal-install`. The next step is to make sure that when you run `cabal` in a terminal, your shell will run the up-to-date version in your home directory. You will want to add the following lines to your shell's configuration file: ```bash PATH=$PATH:$HOME/.cabal/bin alias cabal="$HOME/.cabal/bin/cabal" ``` If you don't know what your shell is, more than likely, your shell is Bash. If you use Bash, the file you will edit is `~/.bashrc`. If you use Z-shell, the file is `~/.zshrc`. You can run the following command to find out what your shell is. ```bash echo $SHELL | xargs basename ``` I use zsh, so that command outputs `zsh` when I run it. Once you do all of that, you'll want to install the additional tools `alex` and `happy`. ```bash $ cabal install alex happy ``` Congratulations! You now have a working Haskell installation! ## Mac OS X ### 10.9 Install the [GHC for Mac OS X](http://ghcformacosx.github.io/) app, which includes GHC and Cabal. It provides instructions on how to add GHC and Cabal to your path after you've dropped the `.app` somewhere. ### 10.6-10.8 Do the binary distribution install described below with [this tarball](https://www.haskell.org/platform/download/2014.2.0.0/ghc-7.8.3-x86_64-apple-darwin-r3.tar.bz2). ## Windows - The [Minimum GHC Installer](https://github.com/fpco/minghc#using-the-installer) is able to compile `network` and other libraries. It includes a minimal GHC environment along with Cabal and MSYS (the compiler environment that allows you to install things like `network`. The [minghc](https://github.com/fpco/minghc) web page does have a few additional details, but note that the default is to install to your local AppData directory rather than a system-wide directory. (C:\Users\\AppData\Local\Programs) ## Other Linux users Download the latest binary distributions for cabal and ghc: - [GHC](http://www.haskell.org/ghc/). - [Cabal](https://www.haskell.org/cabal/download.html). ## Users of other Unix-like Systems Install GHC and Cabal from your package system, then add `~/.cabal/bin` to your `$PATH`. Finally update `cabal` and install the additional tools `alex` and `happy`. ```bash $ cabal update $ cabal install cabal-install alex happy ``` ================================================ FILE: libraries.md ================================================ # Haskell tools for getting things done A curated list of Haskell libraries, packages, and tools ## Data analysis ### Numpy - http://hackage.haskell.org/package/accelerate - http://hackage.haskell.org/package/linear-accelerate - http://hackage.haskell.org/package/repa - http://hackage.haskell.org/package/linear - http://hackage.haskell.org/package/hmatrix (BLAS and LAPACK bindings) ### pandas - http://hackage.haskell.org/package/tables ### Matplotlib / ggplot - http://hackage.haskell.org/package/diagrams ### iPython - https://github.com/gibiansky/IHaskell runs *in* iPython - GHCi (not graphical) ## Data processing ### CSV - https://hackage.haskell.org/package/cassava - http://hackage.haskell.org/package/pipes-csv (streaming, built on Cassava) ================================================ FILE: rts.md ================================================ # Architecture - [Architecture of open source applications](http://www.aosabook.org/en/ghc.html) # Trac Good for digging up recent'ish development history of various topics. - [Trac](https://ghc.haskell.org/trac/ghc/) - [Use this example query to search Trac since the search functionality is useless](https://www.google.com/?gws_rd=ssl#q=site:https:%2F%2Fghc.haskell.org%2Ftrac%2Fghc%2F+garbage+collection) # Memory management / Garbage collection - https://wiki.haskell.org/GHC/Memory_Management - Current GC: [Parallel Generational-Copying Garbage Collection with a Block-Structured Heap; Simon Marlow, Tim Harris, Roshan P. James, Simon Peyton Jones](http://community.haskell.org/~simonmar/papers/parallel-gc.pdf) - Experimental concurrent GC abandoned for worsening performance too much: [Multicore Garbage Collection with Local Heaps; Simon Marlow, Simon Peyton Jones](http://community.haskell.org/~simonmar/papers/local-gc.pdf) - [RTS notes on the garbage collector](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC) # Thread scheduling - [Dynamic Circular Work-stealing Deque; David Chase, Yossi Lev](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.170.1097&rep=rep1&type=pdf) - [Wool - fine grained independent task parallelism in C](https://www.sics.se/~kff/wool/) # GHC commentary - [Commentary top level](https://ghc.haskell.org/trac/ghc/wiki/Commentary) - [RTS](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts) - [Heap and Stack](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage) # Build system - https://ghc.haskell.org/trac/ghc/wiki/Building/Architecture # Porting GHC to a new architecture - https://ghc.haskell.org/trac/ghc/wiki/Building/Porting - https://ghc.haskell.org/trac/ghc/wiki/CrossCompilation ================================================ FILE: specific_topics-ua.md ================================================ # Конкретны теми для користувачів Haskell ### Що роблять синтаксичні конструкції `<-` / `do` / спискове включення? [Чудова стаття](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html) розглядає ці питання. ### Щоб зрозуміти списки та згортання списків (fold) - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### Щоб вивчити деякі відомі класи типів Матеріал, що дуже корисний для розуміння `Functor`, `Applicative`, `Monad`, `Monoid` та інших класів типів в цілому, а також трохи специіфчної для Haskell теорії категорій. - [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Розуміння базових повідомлень про помилки від Haskell - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Лінивість, строгість, стримана рекурсія - [Книга Марлоу](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) (Marlow) про паралелизм та сумісне виконання має одне з найкращих введень в лінивість та нормальні форми. Якщо матеріал з неї не буде засвоюватись, зверніться до інших джерел. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - Питання на Stack Overflow '[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - Слайди з виступу [Johan Tibell](https://github.com/tibbe) на тему [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Маленька демонстрація ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Обов'язково прочитайте документацію та перегляньте реалізацію unsafeDupablePerformIO Коментар з обговорення в Reddit від `glaebhoerl` > Цікаве зауваження: GHC мусить приховувати представлення токену стану за абстрактним типом IO через те, що > токен стану завжду мусть використовуватись лінейно (не дублюватись або бути скинутим), але система типів не може примушувати до цього. > Інша Haskell-подібна мова під назвою Clean має систему унікальних типів (які подібні до лінейних типів і, можливо, інші в аспектах, які я не знаю), > і вони надають можливість прямої передачі World, маючи (не абстрактну) монаду IO тільки для зручності. Оригінал: > Interesting side note: GHC needs to hide the state token representation behind > an abstract IO type because the state token must always be used linearly (not > duplicated or dropped), but the type system can't enforce this. Clean, another > lazy Haskell-like language, has uniqueness types (which are like linear types > and possibly different in ways I'm not aware of), and they expose the > World-passing directly and provide a (non-abstract) IO monad only for > convenience. # Монади та їх трансормери > Не займатесь цим доки ви не розумієете класи типів, Monoid, Functor, Applicative! Самотужки реалізуйте бібліотечні монади (List, Maybe, Cont, Error, Reader, Writer, State) для того, щоб зрозуміти їх краще. Тоді, наприклад, напишіть монадний інтерпретатор невеликої мови виразів за допомогою [Monad Transformers Step by Step](http://catamorph.de/documents/Transformers.pdf) (згадується також нижче, у розділі 'транфсормери монад'). Написання декількох інтерпретаторів простою зміною монад для зміни семантики може надати додаткового розуміння про те, що відбувається. Також заново реалізуйте `Control.Monad`. Функціїї накшталт `mapM` чи `sequence` є чудовою можливістю набути практики з написання узагаленного монадічного коду. У якості путівника можна також використати курс FP, частиною якого також є написання власної реалізації Applicative. Автори: - Коментар на Reddit від htmltyp та Crandom [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Комментар на Reddit від jozefg [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Трансформари монад - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](http://catamorph.de/documents/Transformers.pdf). # Тестування, тести, специфікації, тестування властивостей та генеративне - [Фантастичний посібник](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) від Kazu Yamamoto. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Гарна маленька бібліотека, яка допомогає зрозуміти, як загалом працює потоковий IO. Це знання можна відобразити на бібліотеки типу Pipes та Conduit. # Парсинг у Haskell - [Посібник](https://github.com/JakeWheat/intro_to_parsing) з комбінаторів парсеру із використанням Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Парсинг та генерація JSON Aeson - стандартне рішення для парсингу [JSON](https://json.org) в Haskell. Цей пакет доступний на [hackage](https://hackage.haskell.org/package/aeson) та [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson tutorial](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Структури даних та алгоритми для роботи з графами - [Пакет fgl](https://hackage.haskell.org/package/fgl), зокрема чисто функціональні [алгоритми найкоротшого шляху](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph source from Containers package](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - [Пакет graphs](https://hackage.haskell.org/package/graphs). - [Питання про PHOAS на Stack Overflow](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS for free](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Середовище розробки ## Emacs - [Посібник від Alejandro Serras](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [My dotfiles](https://github.com/bitemyapp/dotfiles/) - [Chris Done's emacs config](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim page on haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Робота із Cabal ## Принципи роботи з Cabal До того, як з'явились так звані сендбокси, користувачі Haskell стикались з проблемою, відомою як Cabal Hell. Встановлення пакетів поза сендбоксом призведе до реєстрації його у базі package-db, що є глобальною для користувача, і зазвичай це не дуже гарна ідея. Виключенням є лише найбазовіші пакети накшталт Cabal, alex, happy. Нічого іншого не мусить встановлюватись у package-db глобальний для системи або користувача окрім випадків, коли ви дійсно знаєте, що робите. Поради як запобігти потраплянню в Cabal Hell, можна прочитати [тут](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). Для того, щоб поекспериментувати із пакетом, або розпочати новий проект, почніть зі створення сендбоксу у новій директорії: `cabal sandbox init`. Якщо коротко: - Завжди використовуйте сендбокси для інсталяції нових пакетів, збирання нових або існуючих проектів, або ж для експериментів. - Для запуску інтерпретатору GHC у контексті проекту, завжди використовуйте `cabal repl`. Рекомендований тут підхід, що базується на використанні сендбоксів, призначений допомогти обійти проблеми із залежностями, але він не сумісний із тим, як Haskell Platform надає готові пакунки. Якщо ви ще тільки вивчаєте Haskell і не розумієте, як працють ghc-pkg and Cabal, *уникайте platform* і замість того використовуйте підхід, що описано раніше в цьому посібнику. ## Stackage Усі користувачі, в яких є проблеми з білдами (зазвичай це користувачі Yesod), мають можливість обміркувати використання Stackage. - Непоганий огляд Stackage можна знайти [тут](https://www.fpcomplete.com/blog/2014/05/stackage-server). Автор вважає, що Stackage, зазвичай, більш корисний, ніж `cabal freeze`. # Hoogle and Haddock ## Шукайте код за сигнатурою типів [Пошуковий сервіс Hoogle](http://www.haskell.org/hoogle/) вміє шукати за типом. Наприклад, подивіться на результати пошуку за виразом `(a -> b) -> [a] -> [b]` [тут](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Ще одне дзеркало [на fpcomplete](https://www.fpcomplete.com/hoogle). Ще є [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (який для пошуку за замовченням використовує увесь зміст hackage). ## Налаштування власної локальної копії Hoogle [Описано тут](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Hackage documentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Зауваження: обидві статті *трошки застаріли*: наприклад, зараз Hackage також показує новесеньку інформацію стосовно статусу білда і документації. ## Що дійсно треба знати Для того, щоб haddocks містив документацію і з пакунків, які стосуються вашого проекту, треба додати `documentation: True` до вашого `~/.cabal/config`. Якщо було використане значення за замовчуванням (`False`) або `False` було встановлене вручну, то перед генерацією haddocks необхідно буде видалити всі ваші пакунки і заново переінсталювати їх. Треба пам'ятати ще одну річ: через те, що Cabal, *а не ви*, інтерпретує параметр `$pkg`, тому параметри `html-location` та `content-location` *мусять бути записані у одинарник лапках* і введені в командний інтерпретатор або записані у скрипті інтерпретатора. Вони не будуть працювати у Makefile через те, що вони будуть інтерпретовані як змінні Make! ```bash #! /usr/bin/env sh # Цю команду можна записати в один рядок, але тоді приберіть слеші cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI Якщо ви є великим шанувальником [TravisCI](https://travis-ci.org), тоді *дуже* рекомендується подивитись на [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) як на базовий приклад `travis.yml` для ваших Haskell-проектів. # Frontend/JavaScript Тут в нас є просто безліч різноманітних варіантів. Ось три базові рекомендації: * [Haste](http://haste-lang.org/) компілятор із Haskell в Javascript - [Компілятор](https://github.com/valderman/haste-compiler) на github. - Чудова [демка](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) використання Haste із реальним проектом. * [GHCJS](https://github.com/ghcjs/ghcjs) - [Введення у GHCJS](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Доволі популярний вибір серед прибічників Haskell, хоча, на відміну від Haste та GHCJS, це не зовсім Haskell. - Написано на Haskell під впливом Haskell - Спробувати PureScript прямо у браузері можна [тут](http://try.purescript.org/) - [Чудовий посібник](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) про те, як почати працювати з PureScript ## Яку мову використовувати для фронтенду І GHCJS, і Haste є повноцінною реалізацією Haskell. Під GHCJS будуть працювати більше Haskell проектів, ніж із Haste, але це не дуже впливає на розробку фронтенд-проектів. Purescript - це зовсім не Haskell і тому використовувати код із бекенду напряму не вийде. GHCJS має найбільший розмір допоміжних бібліотек, необхідних для його работи, який сягає 100Кб (luite працює над цією проблемою). Haste та PureScript більш-менш однакові. Інтеграція із інтструментарем JS найкраща в PureScript (використовується gulp/grunt/bower), в той час як у GHCJS та Haste краще працює із інструментами Haskell (Cabal). Усі три - чудовий вибір і підходять для більшості фронтендових проектів. # Для більш повного розуміння лінивості NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## Дослідницькі папери про ліниве лямбда-числення - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Паралелізм/конкарренсі - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929). Ця книга за авторством Саймона Мерлоу (Simon Marlow) є, мабуть, однією із найкращих книг про паралелізм та конкаренсі - Ґрунтовний [посібник](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) стосовно тестування та інкрементальної розробки багатопотокових програм на Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses та Prisms Після того, як ви набудете певності у роботі із Haskell, поставьтесь серйозно до вивчення Lenses та Prisms, навіть якщо ви просто "користувач". Для того, щоб вони стали вам у нагоді, не треба розуміти базові для них категорії. Люди з легкістю переоцінюють складність використання Lens. Будь-хто із достатнім розумінням Functor/Foldable/Traversable (або навіть лише Functor) може використати лінзи та призми для того, щоб зробити своє життя трішечки краще. Якщо коли небудь ви писали щось типу `(fmap . fmap)`, ви подумки використовували лінзи. Ці дві статті є рекомендованим введенням в тему: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Для подальшої інформації звертайтесь сюда: [Lens package on hackage](http://hackage.haskell.org/package/lens). # Схеми рекурсії Деякі божевільні \*-morphism слова, які ви зустрічали, насправді говорять про рекурсію. Зауважте: перед тим, як переходити до цього матеріалу, треба розуміти, як реалізувати foldr для списків і хочаб ще однієї структури даних, наприклад для дерев (fold - це катаморфізм). Розуміння реалізації unfold (анаморфізм) для тих же структур ще більше полегшить вивчення теми. Цей матеріал пов'язує між собою traversable та foldable. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Цікава демонстрація того, що гілеоморфізм є композицією катаморфізму та анаморфізму. - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - Блискучий практичний досвід - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core та оптимізація швидкості виконання - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Типи та теорія категорій > *НЕ ПОТРІБНА* для того, щоб просто писати на Haskell. Просто для тих, хто цікавиться. Якщо ви маєте час та натхнення набути розуміння типів та теорії категорій: - [Catster's Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) та [Catster's Guide 2](http://byorgey.wordpress.com/catsters-guide-2/) - [Haskell wikibook](http://en.wikibooks.org/wiki/Haskell/Category_theory) містить непогані діаграми - Сторінка [Category Theory](http://www.haskell.org/haskellwiki/Category_theory) у haskellwiki також містить чудові посилання на інші ресурси - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), містить також і практичні приклади. - Список [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) за авторством Пірса. ## Книги - [Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) Рекомендація Кметта (Kmett) - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) та [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). Стандартні підручники з теорії категорій. - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/book.pdf) - найкраще введення у теорію типів із фокусом на мовах програмування. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Інші веселі теми ## Параметричність, ad-hoc та параметричний поліморфізм polymorphism, вільні теореми - [Parametricity](tony_parametricity.pdf). - [TeX оригінали](https://github.com/tonymorris/parametricity/) вищевказанної доповіді - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial та Final, DSL, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) менш релевантна, але все одно цікава стаття. ## Комонади - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, a sequence of three articles by Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (обчислення) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Залежная типізація - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html). - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # Статичная лінковка бінарників - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ================================================ FILE: specific_topics.md ================================================ # Specific topics for Haskell users ### What does that `<-` / `do` / list comprehension syntactic sugar do? Excellent [article](http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html). ### For understanding list and fold - [Explain List Folds to Yourself](http://vimeo.com/64673035) ### For learning some common typeclasses Useful for understanding `Functor`, `Applicative`, `Monad`, `Monoid` and other typeclasses in general but also some Hask-specific category theory: - The [Typeclassopedia](http://www.haskell.org/haskellwiki/Typeclassopedia) ### Understanding basic Haskell error messages - [Understanding basic error messages](http://ics.p.lodz.pl/~stolarek/_media/pl:research:stolarek_understanding_basic_haskell_error_messages.pdf) --- # Laziness, strictness, guarded recursion - Heinrich Apfelmus' article series at https://hackhands.com/guide-lazy-evaluation-haskell/ is excellent. - Marlow's [book](http://chimera.labs.oreilly.com/books/1230000000929/ch02.html) about parallelism and concurrency has one of the best introductions to laziness and normal form I've found. Use other material too if it doesn't stick immediately. - [More points for lazy evaluation](http://augustss.blogspot.hu/2011/05/more-points-for-lazy-evaluation-in.html) - [Oh my laziness!](http://alpmestan.com/posts/2013-10-02-oh-my-laziness.html) - SO question '[Does haskell have laziness?](https://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)' - [Johan Tibell](https://github.com/tibbe)'s slides from a talk on [reasoning about laziness](http://www.slideshare.net/tibbe/reasoning-about-laziness). ## Brief demonstration ```haskell let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched. let (v : _) = a > v 1 > head a -- head a == v 1 let a = 1 * a -- not guarded, (*) is strict > a *** Exception: <> ``` # IO - [Evaluation order and State tokens](https://www.fpcomplete.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens) - [Unraveling the mystery of the IO monad](http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/). - [First class "statements"](http://blog.jle.im/entry/first-class-statements). - [Haddocks for System.IO.Unsafe.unsafePerformIO](http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v:unsafePerformIO) Read the docs and note implementation of unsafeDupablePerformIO Comment from Reddit thread by `glaebhoerl` > Interesting side note: GHC needs to hide the state token representation behind > an abstract IO type because the state token must always be used linearly (not > duplicated or dropped), but the type system can't enforce this. Clean, another > lazy Haskell-like language, has uniqueness types (which are like linear types > and possibly different in ways I'm not aware of), and they expose the > World-passing directly and provide a (non-abstract) IO monad only for > convenience. # Monads and monad transformers > Do not do these until you understand typeclasses, Monoid, Functor, and > Applicative! Implement the standard library monads ( List, Maybe, Cont, Error, Reader, Writer, State ) for yourself to understand them better. Then maybe write an monadic interpreter for a small expression language using [Monad Transformers Step by Step](https://page.mi.fu-berlin.de/scravy/realworldhaskell/materialien/monad-transformers-step-by-step.pdf) paper (mentioned in 'monad transformers' below). Writing many interpreters by just changing the monad to change the semantics can help convey what's going on. Also, reimplement `Control.Monad`. Functions like `mapM` or `sequence` are good opportunities to practice writing generic monadic code. The FP course can be used as a guide to this process, which will also involve writing your own Applicative as well. Credits: - Reddit comment by htmltyp and Crandom [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5aj6). - Reddit comment by jozefg [here](https://www.reddit.com/r/haskell/comments/29eke6/basic_program_ideas_for_learning_about_monads/cik5trg). ## Monad transformers - [A gentle introduction to Monad Transformers](https://github.com/kqr/gists/blob/master/articles/gentle-introduction-monad-transformers.md). - [Monad transformers step-by-step](https://page.mi.fu-berlin.de/scravy/realworldhaskell/materialien/monad-transformers-step-by-step.pdf). # Testing, tests, specs, generative/property testing - This [tutorial](https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/tutorial.md) by Kazu Yamamoto is fantastic. - [Simple-Conduit](https://github.com/jwiegley/simple-conduit): Good simple library for learning how streaming IO works in general, knowledge transferrable to libraries like Pipes and Conduit # Parsing in Haskell - Parser combinator [tutorial](https://github.com/JakeWheat/intro_to_parsing) for Haskell using Parsec - [Writing your own micro-Parsec](http://olenhad.me/articles/monadic-parsers/) ## Parsing and generating JSON Aeson is the standard [JSON](https://json.org) parsing solution in haskell. Available from [hackage](https://hackage.haskell.org/package/aeson) and [github](https://github.com/bos/aeson). - [Parsing JSON using Aeson](http://blog.raynes.me/blog/2012/11/27/easy-json-parsing-in-haskell-with-aeson/) - [Aeson and user created types](http://bitemyapp.com/posts/2014-04-11-aeson-and-user-created-types.html) - [Parsing non-deterministic data with aeson and sum types](http://bitemyapp.com/posts/2014-04-17-parsing-nondeterministic-data-with-aeson-and-sum-types.html) - [Aeson tutorial](https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/json) # Graph algorithms and data structures - The [fgl package](https://hackage.haskell.org/package/fgl) particularly the purely functional shortest path [algos](http://hackage.haskell.org/package/fgl-5.4.2.2/docs/Data-Graph-Inductive-Query-SP.html). - [Inductive graphs and Functional Graph Algorithms](http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01). - [FGL/Haskell - A Functional Graph Library](http://web.engr.oregonstate.edu/~erwig/fgl/haskell/old/fgl0103.pdf). - [Data.Graph source from Containers package](http://hackage.haskell.org/package/containers-0.5.5.1/docs/Data-Graph.html). - The [graphs package](https://hackage.haskell.org/package/graphs). - [SO question about PHOAS](https://stackoverflow.com/questions/24369954/separate-positive-and-negative-occurrences-of-phoas-variables-in-presence-of-rec) - [PHOAS for free](https://www.fpcomplete.com/user/edwardk/phoas). - [Tying the Knot](http://www.haskell.org/haskellwiki/Tying_the_Knot). - [Hackage: dag](https://hackage.haskell.org/package/dag). # Development Environment ## Emacs - [Alejandro Serras's tutorial](https://github.com/serras/emacs-haskell-tutorial/blob/master/tutorial.md) - [My dotfiles](https://github.com/bitemyapp/dotfiles/) - [Chris Done's emacs config](https://github.com/chrisdone/chrisdone-emacs) ## Vim - [Vim page on haskellwiki](http://www.haskell.org/haskellwiki/Vim) - [Haskell-vim-now](https://github.com/begriffs/haskell-vim-now) - [GHC-Mod](https://github.com/kazu-yamamoto/ghc-mod) - [GHC-Mod vim plugin](https://github.com/eagletmt/ghcmod-vim) - [Hindent](https://github.com/chrisdone/hindent) ## Sublime Text - [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell) # Working with Cabal ## Cabal guidelines Cabal Hell was a problem for Haskell users before the introduction of sandboxes. Installing outside of a sandbox will install into your user package-db. This is *not* a good idea except for foundational packages like Cabal, alex, and happy. Nothing else should be installed in the user or global package-dbs unless you know what you're doing. Some best practices for avoiding cabal hell are available [here](http://softwaresimply.blogspot.com/2014/07/haskell-best-practices-for-avoiding.html). To experiment with a package or start a project, begin by doing `cabal sandbox init` in a new directory. Put briefly: - Always use sandboxes for installing new packages, building new or existing projects, or starting experiments - Use `cabal repl` to start a project-scoped ghci instance The sandbox-based approach I suggest should avoid package-dependency problems, but it's incompatible with the way the Haskell Platform provides pre-built packages. If you're still learning Haskell and don't understand how ghc-pkg and Cabal work, *avoid platform* and instead use the install instructions earlier in the guide. ## Stackage For any users (usually Yesod users) that have build problems, consider Stackage. - A good summary of Stackage is [here](https://www.fpcomplete.com/blog/2014/05/stackage-server). In the author's opinion, Stackage is usually more useful than `cabal freeze`. # Hoogle and Haddock ## Search code by type signature The [Hoogle search engine](http://www.haskell.org/hoogle/) can search by type. For example, look at the search results for `(a -> b) -> [a] -> [b]` [here](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%5ba%5d+-%3E+%5bb%5d). Also hosted by fpcomplete [here](https://www.fpcomplete.com/hoogle). Also [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (which has all of hackage enabled for search by default). ## Setting up your own local instance of Hoogle Take a look [here](https://gist.github.com/bitemyapp/3e6a015760775e0679bf). ## Haddock 1. [Fix your hackage documentation](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Fix-your-Hackage-documentation.html) 2. [Hackage documentation v2](http://fuuzetsu.co.uk/blog/posts/2014-01-06-Hackage-documentation-v2.html) Note that these posts are *slightly out of date*: for example, now Hackage sports shiny new info with documentation info and build status. ## What you really need to know In order to have haddocks include documentation for related packages, you have to set `documentation: True` in your `~/.cabal/config`. If it was left on the default (`False`) or set to `False`, you'll have to delete all your packages and reinstall before generating haddocks. The other thing to keep in mind is that due to the way the `$pkg` parameter gets interpolated *by* cabal, not by you, the `html-location` and `content-location` parameters *must be in single quotes* and entered into a shell or contained in a shell script. They will not work in a Makefile, because it will think they are Make variables! ```bash #! /usr/bin/env sh # You can write it one one line by skipping the backslashes cabal haddock --hoogle --hyperlink-source \ --html-location='http://hackage.haskell.org/package/$pkg/docs' \ --contents-location='http://hackage.haskell.org/package/$pkg' ``` # TravisCI If you're as big a fan of [TravisCI](https://travis-ci.org) as I am, then I *strongly* recommend you take a look at [multi-ghc-travis](https://github.com/hvr/multi-ghc-travis) by as the basis of the `travis.yml` for your Haskell projects. # Frontend/JavaScript We have an embarrassment of riches! There are three main choices I would recommend: * [Haste](http://haste-lang.org/) a Haskell to JavaScript compiler - The [compiler](https://github.com/valderman/haste-compiler) on github. - An excellent [demo](http://www.airpair.com/haskell/posts/haskell-tutorial-introduction-to-web-apps) of Haste with an example project. * [GHCJS](https://github.com/ghcjs/ghcjs) - [GHCJS Introduction](http://weblog.luite.com/wordpress/?p=14) - [Functional Reactive Web Interfaces with GHCJS and Sodium](http://weblog.luite.com/wordpress/?p=127) - [Writing Atom plugins in Haskell using ghcjs ](http://edsko.net/2015/02/14/atom-haskell/) * [PureScript](http://www.purescript.org/) - Not strictly Haskell like Haste and GHCJS, but a popular choice among Haskellers - Written in and inspired by haskell - Try purescript in you browser [here](http://try.purescript.org/) - Great guide for [getting started](http://www.christopherbiscardi.com/2014/06/22/getting-started-with-purescript/) ## Which frontend language do I use? GHCJS and Haste are both fully Haskell. GHCJS will work with more Haskell packages than Haste, but this doesn't affect a lot of frontend projects. PureScript isn't Haskell at all, so direct code sharing with your backend will not work. GHCJS has the fattest runtime payload overhead at about 100kb (luite is working on this). Haste and PureScript are competitive. PureScript has the best JS tooling integration (uses gulp/grunt/bower), GHCJS and Haste integrate better with Haskell's tooling (Cabal). All three are great choices and will work for most frontend projects. # For a more thorough understanding of laziness, NF, WHNF - [Notes on lambda calculus](https://vec.io/posts/notes-on-lambda-calculus). ## Research papers about lazy lambda calculi - [A call by need lambda calculus](http://homepages.inf.ed.ac.uk/wadler/topics/call-by-need.html#need-journal). - [Demonstrating Lambda Calculus Reduction](http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf) - [The lazy lambda calculus](http://www.cs.ox.ac.uk/files/293/lazy.pdf). - [Lazy evaluation of Haskell](http://www.vex.net/~trebla/haskell/lazy.xhtml) # Parallelism/Concurrency - [Parallel and Concurrent Programming in Haskell](http://chimera.labs.oreilly.com/books/1230000000929). This book by Simon Marlow is probably the best I've ever read on the topics of Parallelism and Concurrency. - A thorough [walk-through](http://kukuruku.co/hub/haskell/haskell-testing-a-multithread-application) on testing & incremental development of a multi-threaded application in Haskell. - [Functional Reactive Programming](http://www.haskell.org/haskellwiki/Functional_Reactive_Programming) # Lenses and Prisms After you're comfortable with Haskell, strongly consider learning Lenses and Prisms, even if just as a "user". You don't need to understand the underlying category for it to be useful. People vastly overestimate the difficulty of using Lens. Anybody comfortable with Functor/Foldable/Traversable (or even just the first one) can leverage lenses and prisms to make their life happier. If you've ever done something like: `(fmap . fmap)` you were "lensing" in your head. I recommend these two tutorials/introductions: - [A little lens starter tutorial](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial) - [Lens: Lenses, Folds and Traversals](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) Look here for more information: [Lens package on hackage](http://hackage.haskell.org/package/lens). # Recursion Schemes Some of the crazy \*-morphism words you've heard are actually about recursion. NB - before tackling this material you should know how to implement foldr for lists and at least one other data structure, such as a tree. (folds are catamorphisms) Knowing how to implement an unfold (anamorphism) for the same will round things out a bit. This material dovetails with traversable and foldable. - [An introduction to recursion schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/) - [Don't fear the cat](http://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html) - Good demonstration of how hylomorphism is the composition of cata and ana. - [Recursion Schemes](http://comonad.com/reader/2009/recursion-schemes/) - This field guide is excellent. - [Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire](http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf) - [Catamorphisms](https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms) # GHC Core and performance tuning - [Write Haskell as Fast as C](write_haskell_as_fast_as_c.md) - [GHC Wiki: CoreSyn Type](https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType). - [Hackage: GHC Core](https://hackage.haskell.org/package/ghc-core). - [SO Question: Reading GHC Core](https://stackoverflow.com/questions/6121146/reading-ghc-core). - [Haskell as fast as C](http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/). - [Real World Haskell, Chapter 25: Profiling and Optimizations](http://book.realworldhaskell.org/read/profiling-and-optimization.html). # Type and Category Theory > *Not* needed to actually write Haskell, just for those interested! If you want to follow up on type and category theory: - [Catster's Guide](http://byorgey.wordpress.com/2014/01/14/catsters-guide/) and [Catster's Guide 2](http://byorgey.wordpress.com/catsters-guide-2/) - The [haskell wikibook](http://en.wikibooks.org/wiki/Haskell/Category_theory) has nice diagrams - [Category Theory](http://www.haskell.org/haskellwiki/Category_theory) on haskellwiki, also has good links to other resources - [Categories from scratch](http://science.raphael.poss.name/categories-from-scratch.html), Includes some practical examples. - Pierce's [Great Works in PL](http://www.cis.upenn.edu/~bcpierce/courses/670Fall04/GreatWorksInPL.shtml) list. ## Books - [Quora Question: What is the best textbook for category theory?](http://www.quora.com/Category-Theory/What-is-the-best-textbook-for-Category-theory?share=1) Kmett's recommendations - [Awodey](http://ukcatalogue.oup.com/product/9780199237180.do) and [MacLane](http://www.amazon.com/Categories-Working-Mathematician-Graduate-Mathematics/dp/0387984038). The standard textbooks on category theory. - [Harper's Practical Foundations for Programming Languages](http://www.cs.cmu.edu/~rwh/plbook/1sted-revised.pdf) is the best PL focused intro to type theory I've read. - [Type theory and Functional Programming](http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/). # Metaprogramming ## Generics Generics are usually used to generate typeclass instances, but you'll see TH used for that purpose too. - https://ocharles.org.uk/blog/posts/2014-04-26-constructing-generically.html - Current docs: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#generic-programming ## QuasiQuotation - Simple example, nice for avoiding gnarly escape sequences in strings: https://hackage.haskell.org/package/raw-strings-qq-1.0.2/docs/Text-RawString-QQ.html - Tutorial: https://www.fpcomplete.com/user/marcin/quasiquotation-101 - http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ ## Template Haskell - http://www.parsonsmatt.org/programming/2015/11/15/template_haskell.html (Great tutorial, strongly recommended even if the Ruby doesn't mean much to you) - https://www.fpcomplete.com/user/marcin/template-haskell-101 - https://ocharles.org.uk/blog/guest-posts/2014-12-22-template-haskell.html - Current docs: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell - OCaml and TH slides: https://nicolaspouillard.fr/talks/cufp-metaprogramming-tutorial-slides.pdf - http://illustratedhaskell.org/index.php/2011/09/24/template-haskell-tutorial/ (old) - https://stackoverflow.com/questions/10857030/whats-so-bad-about-template-haskell (warnings about TH) # Other fun topics ## Parametricity, ad-hoc vs. parametric polymorphism, free theorems - [Parametricity](tony_parametricity.pdf). - [TeX sources](https://github.com/tonymorris/parametricity/) for the above talk. - [Making ad-hoc polymorphism less ad-hoc](http://swizec.com/blog/week-20-making-ad-hoc-polymorphism-less-ad-hoc/swizec/6564). - [Theorems for Free!](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). ## Initial and Final, DSLs, Finally Tagless - [Final Encodings, Part 1: A Quick Demonstration](http://creativelad.wordpress.com/2013/11/28/final-encodings-part-1-a-quick-demonstration/). - [Transforming Polymorphic Values](http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/). - [GADTs in Haskell 98](http://martijn.van.steenbergen.nl/journal/2009/11/12/gadts-in-haskell-98/). - [Typed Tagless-Final Linear Lambda Calculus](https://www.fpcomplete.com/user/mutjida/typed-tagless-final-linear-lambda-calculus). - [Typed tagless-final interpretations: Lecture notes](http://okmij.org/ftp/tagless-final/course/course.html). - [Typed Tagless Final Interpreters](http://okmij.org/ftp/tagless-final/course/lecture.pdf). - [The dog that didn't bark](http://existentialtype.wordpress.com/2011/03/21/the-dog-that-didnt-bark/) less specifically relevant but interesting. ## Comonads - [Comonads in Haskell](https://speakerdeck.com/dmoverton/comonads-in-haskell). - [SO question: Can a Monad be a Comonad](https://stackoverflow.com/questions/16551734/can-a-monad-be-a-comonad). ## Yoneda / CoYoneda - [SO question: Step-by-step explanation of coyoneda](https://stackoverflow.com/questions/24000465/step-by-step-deep-explain-the-power-of-coyoneda-preferably-in-scala-throu). - Free monads for Less, a sequence of three articles by Edward Kmett * [Part 1: Codensity](http://comonad.com/reader/2011/free-monads-for-less/). * [Part 2: Yoneda](http://comonad.com/reader/2011/free-monads-for-less-2/). * [Part 3: Yielding IO](http://comonad.com/reader/2011/free-monads-for-less-3/). ## Propositions vs. Judgments (computation) - [StackExchange question: What is the difference between propositions and judgements](http://cstheory.stackexchange.com/questions/9826/what-is-the-difference-between-propositions-and-judgments). - [Lecture notes from a short, three lecture course](http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/OtherInformation/article.pdf) # Dependent typing - [Grokking sum types, value constructors, and type constructors](http://bitemyapp.com/posts/2014-04-05-grokking-sums-and-constructors.html) squint hard. - [Lightweight Dependent-type Programming](http://okmij.org/ftp/Computation/lightweight-dependent-typing.html). - [Idris programming language](http://www.idris-lang.org/). # Statically linking binaries - [Static linking](https://wiki.haskell.org/Web/Literature/Static_linking) - [Static linking with GHC on Arch Linux](http://www.edofic.com/posts/2014-05-03-ghc-arch-static.html) - [Statically linking Linux binaries for ARM & MIPS](https://stackoverflow.com/questions/14270177/ghc-statically-linking-linux-binaries-for-arm-mips-processors) - [Statically link GMP using GHC and LLVM](https://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) ================================================ FILE: tools.md ================================================ # Tools ## Don't install or try to use ghc-mod if you're a beginner It's a bit fragile, more than a bit slow, and it's not worth the grief. ## Text Editors - Emacs - [Install haskell-mode](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L31) - [Install flycheck](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L29) - Enable and configure Haskell, this can be just `(require 'haskell)` if you don't care about anything else. - [Enable flycheck](https://github.com/bitemyapp/dotfiles/blob/master/.emacs#L97) - Symlink Stack to `/usr/bin` or otherwise make sure flycheck can find it - [dunzo.](https://twitter.com/bitemyapp/status/693621160571985920) - Vim - We recommend [Stephen Diehl's vim instructions](http://www.stephendiehl.com/posts/vim_2016.html) but we suggest replacing ghc-mod with the below for now. - For getting type errors in vim reliably (in lieu of ghc-mod) ``` autocmd FileType haskell setlocal makeprg=stack\ build autocmd FileType haskell setlocal errorformat=%f:%l:%v:%m ``` from: https://github.com/ishiy1993/dotfiles/blob/master/.vimrc - [Sublime Text](https://github.com/SublimeHaskell/SublimeHaskell) - [Atom](https://atom.io/packages/ide-haskell) - [IntelliJ](https://github.com/carymrobbins/intellij-haskforce) - Notepad++ has basic Haskell support built in. - gedit has basic Haskell support built in. ## Other - Haskell For Mac ================================================ FILE: write_haskell_as_fast_as_c.md ================================================ # Write Haskell as fast as C: exploiting strictness, laziness and recursion - 2008-05-16 - by Don Stewart (dons) - Originally posted at "Haskell Hacking: a journal of Haskell programming" In a recent mailing list thread Andrew Coppin complained of poor performance with "nice, declarative" code for computing the mean of a very large list of double precision floating point values: ```haskell import System.Environment import Text.Printf mean :: [Double] -> Double mean xs = sum xs / fromIntegral (length xs) main = do [d] <- map read `fmap` getArgs printf "%f\n" (mean [1 .. d]) ``` Which, when executed, churns away for a while, but eventually runs out of memory: ```bash $ ghc -O2 --make A.hs $ time ./A 1e9 A: out of memory (requested 1048576 bytes) ./A 1e9 12.74s user 1.20s system 99% cpu 13.997 total ``` Well, it got 13 seconds into the job doing something. At least it was making progress. While Andrew was citing this as an example of GHC Haskell being unpredictable (it's not an example of that, as we'll see), there is something here -- this little program reveals a lot about the interaction between strictness, laziness and approaches to compiler optimisation in Haskell. This post is about writing reliably fast code, and then how to write more naive code that is also reliably fast. In particular, how recursion consistently produces excellent code, competitive with heavily optimised C, and how to get similar results from higher order functions. Throughout this post I'll be using GHC 6.8.2, with -O2. Sometimes I'll switch to the C backend (-fvia-C -optc-O2). Also, I don't care about smarter ways to implement this -- we're simply interested in understanding the compiler transformations involved in the actual loops involved. Understanding strictness and laziness First, let's work out why this ran out of memory. The obvious hard constraint is that we request a list of 1e9 doubles: that is very, very large. It's 8 * 10^9 bytes, if allocated directly, or about 7.5G. Inside a list there is yet further overhead, for the list nodes, and their pointers. So no matter the language, we simply cannot allocate this all in one go without burning gigabytes of memory. The only approach that will work is to lazily generate the list somehow. To confirm this, we can use a strict list data type, just to see how far we get. First, let's define a strict list data type. That is one whose head and tail are always fully evaluated. In Haskell, strictness is declared by putting bangs on the fields of the data structure, though it can also be inferred based on how values are used: ```haskell data List a = Empty | Cons !a !(List a) ``` This is a new data type, so we'll need some new functions on it: ```haskell length' :: List a -> Int length' = go 0 where go n Empty = n go n (Cons _ xs) = go (n+1) xs sum' :: Num a => List a -> a sum' xs = go 0 xs where go n Empty = n go n (Cons x xs) = go (n+x) xs enumFromTo' :: (Num a, Ord a) => a -> a -> List a enumFromTo' x y | x > y = Empty | otherwise = go x where go x = Cons x (if x == y then Empty else go (x+1)) ``` I've written these in a direct worker/wrapper transformed, recursive style. It's a simple, functional idiom that's guaranteed to get the job done. So now we can compute the length and sum of these things, and generate one given a range. Our 'mean' function stays much the same, just the type changes from a lazy to strict list: ```haskell mean :: List Double -> Double mean xs = sum' xs / fromIntegral (length' xs) ``` Testing this, we see it works fine for small examples: ```haskell $ time ./B 1000 500.5 ./A 1000 0.00s user 0.00s system 0% cpu 0.004 total ``` But with bigger examples, it quickly exhausts memory: ```haskell $ time ./B 1e9 Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize' to increase it. ./A 1e9 0.02s user 0.02s system 79% cpu 0.050 tota ``` To see that we can't even get as far as summing the list, we'll replace the list body with undefined, and just ask for the list argument to be evaluated before the body with a bang patterns (a strictness hint to the compiler, much like a type annotation suggests the desired type): ```haskell mean :: List Double -> Double mean !xs = undefined main = do [d] <- map read `fmap` getArgs printf "%f\n" (mean (enumFromTo' 1 d)) ``` And still, there's no hope to allocate that thing: ```bash $ time ./A 1e9 Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize' to increase it. ./A 1e9 0.01s user 0.04s system 93% cpu 0.054 total ``` Strictness is not the solution here. Traversing structures and garbage collection So why is the naive version actually allocating the whole list anyway? It was a lazy list, shouldn't it somehow avoid allocating the elements? To understand why it didn't work, we can look at what: ```haskell mean :: [Double] -> Double mean xs = sum xs / fromIntegral (length xs) ``` actually means. To reason about the code, one way is to just look at the final, optimised Haskell GHC produces, prior to translation to imperative code. This reduced Haskell is known as "core", and is the end result of GHC's optimisations-by-transformation process, which iteratively rewrites the original source into more and more optimised versions. Referring to the core is useful if you're looking for C-like performance, as you can state precisely, to the register level, what your program will do -- there are no optimisations to perform that would confuse the interpretation. It is an entirely unambiguous form of Haskell, so we'll use it to clarify any uncertainties. (For everyday programming, a comfortable knowledge of laziness and strictness is entirely adequate, so don't panic if you don't read core!). To view the core, we can use ghc -O2 -ddump-simpl, or the ghc-core tool. Looking at it for the naive program we see that 'mean' is translated to: ```haskell $wlen :: [Double] -> Int# -> Int# ... $wsum'1 :: [Double] -> Double# -> Double# ... main = ... shows ( let xs :: [Double] xs = enumFromTo1 lvl3 d_a6h in case $wsum'1 xs 0.0 of { _ -> case $wlen xs 0 of { z -> case ww_s19a /## (int2Double# z) of { i -> D# i ) ``` It looks like a lot of funky pseudo-Haskell, but its made up of very simple primitives with a precise meaning. First, length and sum are specialised -- their polymorphic components replaced with concrete types, and in this case, those types are simple, atomic ones, so Double and Int are replaced with unlifted (or unboxed) values. That's good to know -- unlifted values can be kept in registers. We can also confirm that the input list is allocated lazily. ```haskell let xs :: [Double] xs = enumFromTo1 lvl3 d_a6h in .. ``` The 'let' here is the lazy allocation primitive. If you see it on non-unboxed type, you can be sure that thing will be lazily allocated on the heap. Remember: core is like Haskell, but there's only 'let' and 'case' (one for laziness, one for evaluation). So that's good. It means the list itself isn't costing us anything to write. This lazy allocation also explains why we're able to make some progress before running out of memory resources -- the list is only allocated as we traverse it. However, all is not perfect, the next lines reveal: ```haskell case $wsum'1 xs 0.0 of { _ -> case $wlen xs 0 of { z -> case ww_s19a /## (int2Double# z) of { i -> D# i ``` Now, 'case' is the evaluation primitive. It forces evaluation to the outermost constructor of the scrutinee -- the expression we're casing on -- right where you see it. In this way we get an ordering of operations set up by the compiler. In our naive program, first the sum of the list is performed, then the length of the list is computed, until finally we divide the sum by the length. That sounds fine, until we think about what happened to our lazily allocated list. The initial 'let' does no work, when allocating. However, the first 'sum' will traverse the entire list, computing the sum of its elements. To do this it must evaluate the entire huge list. Now, on its own, that is still OK -- the garbage collector will race along behind 'sum', deallocating list nodes that aren't needed anymore. However, there is a fatal flaw in this case. 'length' still refers to the head of the list. So the garbage collector cannot release the list: it is forced to keep the whole thing alive. 'sum', then, will allocate the huge list, and it won't be collected till after 'length' has started consuming it -- which is too late. And this is exactly as we observed. The original poster's unpredictably is an entirely predictable result if you try to traverse a 7G lazy list twice. Note that this would be even worse if we'd been in a strict language: the initial 'let' would have forced evaluation, so you'd get nowhere at all. Now we have enough information to solve the problem: make sure we make only one traversal of the huge list. so we don't need to hang onto it. Lazy lists are OK The simple thing to do then, and the standard functional approach for the last 40 years of functional programming is to write a loop to do both sum and length at once: ```haskell mean :: [Double] -> Double mean = go 0 0 where go :: Double -> Int -> [Double] -> Double go s l [] = s / fromIntegral l go s l (x:xs) = go (s+x) (l+1) xs ``` We just store the length and sum in the function parameters, dividing for the mean once we reach the end of the list. In this way we make only one pass. Simple, straight forward. Should be the standard approach in the Haskell hackers kit. By writing it in an obvious recursive style that walks the list as it is created, we can be sure to run in constant space. Our code compiles down to: ```haskell $wgo :: Double# -> Int# -> [Double] -> Double# $wgo x y z = case z of [] -> /## x (int2Double# y); x_a9X : xs_a9Y -> case x_a9X of D# y_aED -> $wgo (+## x y_aED) (+# y 1) xs_a9Y ``` We see that it inspects the list, determining if it is an empty list, or one with elements. If empty, return the division result. If non-empty, inspect the head of the list, taking the raw double value out of its box, then loop, On a small list: ```bash $ time ./B 1000 500.5 ./B 1000 0.00s user 0.00s system 0% cpu 0.004 total ``` On the 7 gigabyte list: ```bash $ time ./B 1e9 500000000.067109 ./B 1e9 68.92s user 0.19s system 99% cpu 1:09.57 total ``` Hooray, we've computed the result! The lazy list got us home. But can we do better? Looking at the GC and memory statistics (run the program with +RTS -sstderr ) we can see how much work was going on: ``` 24,576 bytes maximum residency (1 sample(s)) %GC time 1.4% (4.0% elapsed) Alloc rate 2,474,068,932 bytes per MUT second Productivity 98.6% of total user ``` What does this tell us? Firstly, garbage collection made up a tiny fraction of the total time (1.4%), meaning the program was doing productive thing 98.6% of the time -- that's very good. Also, we can see it ran in constant space: 24k bytes maximum allocated in the heap. And the program was writing and releasing these list nodes at an alarming rate. 2G a second (stunning, I know). Good thing allocation is cheap. However, this does suggest that we can do better -- much better -- by avoiding any list node allocation at all and keeping off the bus. We just need to prevent list nodes from being allocated at all -- by keeping only the current list value in a register -- if we can stay out of memory, we should see dramatic improvements. Recursion kicks arse So let's rewrite the loop to no longer take a list, but instead, the start and end values of the loop as arguments: ```haskell mean :: Double -> Double -> Double mean n m = go 0 0 n where go :: Double -> Int -> Double -> Double go s l x | x > m = s / fromIntegral l | otherwise = go (s+x) (l+1) (x+1) main = do [d] <- map read `fmap` getArgs printf "%f\n" (mean 1 d) ``` We've moved the list lower and upper bounds into arguments to the function. Now there are no lists whatsover. This is a fusion transformation, instead of two separate loops, one for generation of the list, and one consuming it, we've fused them into a single loop with all operations interleaved. This should now avoid the penalty of the list memory traffic. We've also annotated the types of the functions, so there can be no ambiguity about what machine types are used. Looking at the core: ```haskell $wgo_s17J :: Double# -> Int# -> Double# -> Double# $wgo_s17J x y z = case >## z m of False -> $wgo_s17J (+## x z) (+# y 1) (+## z 1.0); True -> /## x (int2Double# y) ``` it is remarkably simple. All parameters are unboxed, the loop is tail recursive, and we can expect zero garbage collection, all list parameters in registers, and we'd expect excellent performance. The >## and +## are GHC primitives for double comparison and addition. +# is normal int addition. Let's compile it with GHC's native code generator first (-O2 -fexcess-precision): ```bash $ time ./C 1e9 500000000.067109 ./C 1e9 3.75s user 0.00s system 99% cpu 3.764 total ``` Great. Very good performance! The memory statistics tell a similar rosy story: 20,480 bytes maximum residency (1 sample(s)) %GC time 0.0% (0.0% elapsed) Alloc rate 10,975 bytes per MUT second Productivity 100.0% of total user So it ran in constant space, did no garbage collection, and was allocating only a few bytes a second. Recursion is the breakfast of champions. And if we use the C backend to GHC: (-O2 -fexcess-precision -fvia-C -optc-O2), things get seriously fast: ```bash $ time ./C 1e9 500000000.067109 ./C 1e9 1.77s user 0.00s system 99% cpu 1.776 total ``` Wow, much faster. GCC was able to really optimise the loop GHC produced. Good job. Let's see if we can get this kind of performance in C itself. We can translate the recursive loop directly into a for loop, where function arguments becomes the variables in the loop: ```c #include #include int main(int argc, char **argv) { double d = atof(argv[1]); double n; long long a; // 64 bit machine double b; // go_s17J :: Double# -> Int# -> Double# -> Double# for (n = 1, a = 0, b = 0; n <= d; b+=n, n++, a++) ; printf("%f\n", b / a); return 0; } ``` That was quite straight forward, and the C is nicely concise. It is interesting to see how function parameters are updated in place explicitly in the C code, while its implicitly reusing stack slots (or registers) in the functional style. But they're really describing the same code. Now, compiling the C without optimisations: ```bash $ time ./a.out 1e9 500000000.067109 ./a.out 1e9 4.72s user 0.00s system 99% cpu 4.723 total ``` Ok. That's cool. We got the same results, and optimised Haskell beat unoptimsed C. Now with -O, gcc is getting closer to catch GHC: ```bash $ time ./a.out 1e9 500000000.067109 ./a.out 1e9 2.10s user 0.00s system 99% cpu 2.103 total ``` And with -O2 it makes it in front by a nose: ```bash $ time ./a.out 1e9 500000000.067109 ./a.out 1e9 1.76s user 0.00s system 99% cpu 1.764 total ``` gcc -O2 wins the day (barely?), just sneaking past GHC -O2, which comes in ahead of gcc -O and -Onot. We can look at the generated assembly (ghc -keep-tmp-files) to find out what's really going on.. GCC generates the rather nice: ```asm .L6: addsd %xmm1, %xmm2 incq %rax addsd %xmm3, %xmm1 ucomisd %xmm1, %xmm0 jae .L6 .L8: cvtsi2sdq %rax, %xmm0 movl $.LC2, %edi movl $1, %eax divsd %xmm0, %xmm2 ``` Note the very tight inner loop, and final division. Meanwhile, GHC produces, with its native code backend: ```asm s1bn_info: ucomisd 5(%rbx),%xmm6 ja .Lc1dz movsd %xmm6,%xmm0 addsd .Ln1dB(%rip),%xmm0 leaq 1(%rsi),%rax addsd %xmm6,%xmm5 movq %rax,%rsi movsd %xmm0,%xmm6 jmp s1bn_info .Lc1dz: cvtsi2sdq %rsi,%xmm0 divsd %xmm0,%xmm5 ``` Quite a bit more junk in the inner loop, which explains the slowdown with -fasm. That native code gen needs more work for competitive floating point work. But with the GHC C backend: ```asm s1bn_info: ucomisd 5(%rbx), %xmm6 ja .L10 addsd %xmm6, %xmm5 addq $1, %rsi addsd .LC1(%rip), %xmm6 jmp s1bn_info .L10: cvtsi2sdq %rsi, %xmm7 divsd %xmm7, %xmm5 ``` Almost identical to GCC, which explains why the performance was so good! Some lessons Lesson 1: To write predictably fast Haskell -- the kind that competes with C day in and out -- use tail recursion, and ensure all types are inferred as simple machine types, like Int, Word, Float or Double that simple machine representations. The performance is there if you want it. Lesson 2: Laziness has an overhead -- while it allows you to write new kinds of programs (where lists may be used as control structures), the memory traffic that results can be a penalty if it appears in tight inner loops. Don't rely laziness to give you performance in your inner loops. Lesson 3: For heavy optimisation, the C backend to GHC is still the way to go. Later this year a new bleeding edge native code generator will be added to GHC, but until then, the C backend is still an awesome weapon. In a later post we'll examine how to get the same performance by using higher order functions.