4 ms·
Thanks for pointing that out. The author didn't emphasize that point, and it makes sense now. Is it me, or was it a bad example for where Haskell "really shin
by iamdev 13y ago
Thanks for pointing that out. The author didn't emphasize that point, and it makes sense now.
Is it me, or was it a bad example for where Haskell "really shines"? I don't like the "use Haskell cause it has these really cool functions" approach. Feels so superficial.
- scarmig 13y agoI think the strongest argument for Haskell is what you can make it not do, not what you can make it do. Having strong and concise type guarantees is great. Haskell's a great example of that. So is Ocaml.
- nahiluhmot 13y agoIt wasn't so much a bad example so much as it was a trivial one. Perhaps a more powerful one (that displays the advantages of lazy evaluation and higher-order functions) would be the function to generate an infinite list of Fibonacci numbers. fibs :: [Integer] fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Even still, it's difficult to get the feel of actually using the language from one function taken from a freshman year CS class.
- cgh 13y agoHow about demonstrating the power of laziness by generating the power set of a set? (Taken from Learn You a Haskell). powerset :: [a] -> [[a]] powerset xs = filterM (\x -> [True, False]) xs ghci> powerset [1,2,3] [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]] Edit: I read LYaH some time ago but this example stuck with me because it's both wonderful and mind-blowing.
- platz 13y agoHere's a recursive definition which is less cool but less 'magic' powerset :: [a] -> [[a]] powerset [] = [[]] powerset (x:xs) = yss ++ map (x:) yss where yss = powerset xs > powerset [1,2,3] [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]
- freyrs3 13y agoYou're right, it wasn't a particularly compelling example of Haskell's strengths.
- implicit_cast 13y agoIt's not just you. Haskell is worth the effort, but I don't think the article's author did a great job of articulating why. Some things I've noticed: Haskell does not automatically admit an extra "null" value to every type, so you can ordinarily ignore NullPointerExceptions and the like. When you do need a nullable bit of data, you have to do some extra work: You must rename the type from "Foo" to "Maybe Foo" and change all the callsites. These callsites must test for null and specify what happens. (there exists a non-terminating explode() function if you really want it) The build will fail until every last case is covered. This is great for reliability. Most data in Haskell is immutable. This encourages good programming practice, sure, but it really pays off when you start writing parallel code. Parallel Haskell is by far the easiest way I know to write fast concurrent stuff. On that note, Haskell's concurrency primitives are very well-designed. Haskell's solution to callback hell is more general and powerful than anything I know. The "do" block is really just super elegant syntax sugar for a CPS chain. Our unit test suite does not intermittently fail. We restrict side effects such that our build will fail if a test tries to do non-faked I/O. It took a bit of effort to build, but normal use is effortless.