3 ms·
> not because of deficiencies in [Haskell], but because it’s politically difficult to get people to use a Haskell based language I know tons of languages, but
by csense 13y ago
> not because of deficiencies in [Haskell], but because it’s politically difficult to get people to use a Haskell based language
I know tons of languages, but I've never really been able to understand Haskell. The whole monad thing is just...weird. I've read several descriptions, and had it explained to me multiple times on HN, but I still just Don't Get It. And I feel like I should Get It, because I have a degree in math including an upper-level course in logic.
To me, that suggests a problem with the language design of Haskell -- maybe monads are a bad abstraction, maybe the syntax should be different, maybe there's a brilliant and simple explanation that I haven't found yet. But the bottom line is that the learning curve for people coming from other languages needs to be a lot lower for Haskell to ever be anything but a tiny niche.
- FreeFull 13y agoThere isn't much to Monads at all. One problem that some Haskell beginners hit is that they read some bunk monad explanations and only get confused, and that monads get so hyped up that when met with the actual description, they try to look for something more that isn't actually there. Monads are just a set two or three operations on a data structure, which obey certain laws. The operations are either ( map(function,structure), collapse(structure), create(value) ) or ( bind(function,structure), create(value) ) where you can implement map and collapse in terms of bind, and vice versa. You don't even need to know the laws to use monads, only to create a new monad. map(function,structure) is a function that applies a function to every element in the structure. Pretty straightforward. For example: -> map(addThree,[1,2,3]) [4,5,6] Collapse is a function which takes structures embedded in a structure of the same type, and gets rid of one level. For lists, it's the same as concatenating all sublists. -> collapse([[],[3,4],[6,1,2]]) [3,4,6,1,2] Create takes a value and puts it into the structure in the simplest way possible. -> create(3) [3] These three functions are enough to have a monad over your structure, and are how monads are usually defined in mathematics. But lets look at the alternative. For the sake of explaining bind, let's introduce a new function which we will just use as an example: -> func makeThree(value): return [value,value+1,value+2] Let's say we have a list of values [3,1,5] and we want to apply makeThree on it to get a new list. Let's try doing it using map. -> map(makeThree,[3,1,5]) [[3,4,5],[1,2,3],[5,6,7]] We got a list of lists rather than just the simple list we wanted, but we can use collapse to get it into what we want: -> collapse(map(makeThree,[3,1,5])) [3,4,5,1,2,3,5,6,7] And here is an example of using bind to do the same thing: -> func bind(function,structure): return collapse(map(function,structure)) -> bind(makeThree,[3,1,5]) [3,4,5,1,2,3,5,6,7] This definition of bind is valid for all monads. I have used the list monad as an example here, but many other structures are also monads. You don't really see the power of what you can really do with monads until you use them in a language that supports them well. In the actual definition of monads, collapse is called join. The definition using bind is the one that is more popular in programming, while the definition using join and map is more popular in mathematics. I'm not actually going to show what the laws governing the interactions between these functions are in this comment, but I can explain them if you ask.
- phyalow 13y agoTDIL, thanks!
- nhaehnle 13y agoI agree, except that I think Haskell would be pretty big in an alternative universe where everybody already learns programming with Haskell. That is, in the dynamic system of software development, default-to-imperative and default-to-pure-functional are both stable equilibria. As far as monads go, the things that helped me was (1) think of writing in monads not as programming in an imperative language, but as writing a functional program that returns an imperative program (as a value in a rather opaque type), and (2) forget about do-notations and learn about using the arrow-like operators directly.