TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Haskell IO for Imperative Programmers

45 点作者 benwr超过 15 年前

4 条评论

yason超过 15 年前
I don't want to come out as a language troll -- I have written enough and much liked Haskell -- but one thing that Clojure, my favorite language, got right is multiparadigm programming.<p>Because I/O is serial and imperative by nature it just so much makes sense to handle I/O in a serial and imperative way and write the rest of the program in functional style. The same can be said of state and assignments: you need persistent state at _some_ point in runtime, and I think it's best to accept the crap and be explicit about it.<p>I greatly appreciate the idea of monads and all the insight that went into them, but it seems to me that they were conceived merely to solve a problem that doesn't need to exist. Monads are a great academic hallelujah and I hope they lead to the discovery of some new, unfamiliar programming paradigm that benefits all programmers.<p>However, I think monads are currently like the various design patterns akin to the Visitor (and its relatives) in Java. People had to invent these patterns basically to emulate a plain old function pointer bundled with userdata pointer. That's an old "trick" from C in the 70's and assembly before that, but only such that is otherwise unavailable in Java.<p>Consequently, if you're all pure and lazy-evaluating and you decide to make that a principal issue then yes, you do need monads to do the simplest thing, such as I/O, simply to fit into the purely lazy environment. IIRC the I/O monad was where it all began -- I would be surprised to note otherwise.<p>Then again, what I like in Clojure is that while the program control isn't automatically lazy-evaluating I still get most of the benefits of laziness from the fact that almost all data flow in Clojure is lazy by default. I can still write these nice infinite Fibonacci series or infinite sequences of random numbers and (take) as much as I need. And I still have (delay) explicitly for any body of code that I need evaluated lazily. And I can still enjoy writing most of my code in beautiful pure functional Lisp.<p>Yet I _can_ still shuffle my data procedurally. And loop around I/O like a grumpy Pascal hacker in a hamster wheel as much as I want _when_ I need to. And still confine that mess into a function or two with big warning labels around, so to not contaminate the rest of my program.<p>I know there are people who build incredible things out of monads, or inventing monadic metatypes I'm unable to grasp, and generally doing stuff never done before.<p>But that is merely a sign of great cleverness of these people; the same can be said about C++ templates that you can whack into such a spaghetti that they actually run parts of your computation in compile time.<p>One could, I suppose, say that it's like a treadmill with wheels that are connected to the running belt but slightly downgeared: you can use it to move on a street by exercising walking with your legs but most people choose to just.. you know, walk directly.
评论 #930960 未加载
评论 #930726 未加载
评论 #930736 未加载
Luyt超过 15 年前
The author makes a nice case for lazy evaluation, but I doubt the "goal to help experienced procedural programmers make the transition to Haskell" is achieved because he doesn't explain how to read special Haskell constructs:<p><pre><code> mapM_ (interactFile (unlines . map processIt . lines)) args ss &#60;- mapM readFile fileNames putStr $ f (concat ss) </code></pre> A c++ programmer might ask: What do these dots means? Wat does the $ character do? Why us mapM sometimes used with and without trailing underscore?<p>It seems like one should learn Haskell first, before being able to understand the examples.
评论 #930991 未加载
WilliamLP超过 15 年前
&#62; safeRead s = catch (readFile s) $ \_ -&#62; return ""<p>&#62; Contrasting this with Java is left as an exercise for the reader.<p>String safeRead(String fName) {<p><pre><code> try { return readFile(fName); } catch (Exception e) { return ""; } </code></pre> }<p>Just the same thing, except replace ASCII garbage with words? (It assumes I have a readFile function, but that's not such a terrible thing to have around...)
评论 #930972 未加载
评论 #930582 未加载
shrughes超过 15 年前
I really despise tutorials that extol the benefits of laziness by demonstrating interact and getContents, the most evil functions in the Haskell library.
评论 #930598 未加载