Abstractions in Haskell are smaller, more universal and composable than those of say ruby or python. For example the very simple idea of a Monoid (essentially concatenation) can be found in most places either explicitly or if you squint a bit, and once you recognise it a whole set of properties and behaviours can be reused.
Also once the structure is in place, they types make for very safe re-factoring and assurance that you haven't broken anything.
The only thing that's probably slower than ruby in Haskell is, unfortunately, learning it in the first place :-)
There are definitely some more general uses of the Monoid type class than concatenation that don't require newtypes, but they are slightly harder to understand, so they don't tend to get trotted out as examples. The best example I can think of is Ordering (LT | EQ | GT), which is a monoid in the sense of lexicographical ordering. You also have Function (a -> b) and Maybe b, which are each monoids when b is a monoid, but if b is a monoid under concatenation then those just look like concatenation too.
One other reason I think they're thought of as concatenation is that monoids under concatenation are extremely useful. The most common case is when appending things that are like strings. Strings are not performant, so for anything significant you want to use Text or ByteString. However, it's not uncommon to use Strings when you're first figuring things out. If you want to then switch over to Text and you used String appending (++), you'll have to find and replace every instance of that. If you instead used Monoid appending (<>), you can switch the types and everything will still work. Quite nice.
newtype Sum = Sum { getSum :: Int }
instance Monoid Sum where
mempty = Sum 0
mappend (Sum a) (Sum b) = Sum (a + b)I was trying to simplify to get a cross the point that the Haskell ecosystem contains small and very well factored abstractions, without busting out the mathjax and technical terms. I find the key understanding of Monoids (which lets me use them and gives me a useful intuition upon seeing one) to be "Oh this is just combining these things together" - which I explain to newcomers as "basically concatenation".
It's always hard to pick the correct amount of correctness to use :-)
http://hackage.haskell.org/package/generic-deriving-1.6.2/do...
Then you can think of it as concatenating two unary numbers.
Essentially, there are three sitations:
a) Everything is of the same difficulty. b) Haskell is more difficult than Ruby. c) Ruby is more difficult than Haskell.
I'd say (b) is a much saner conclusion.
Accordingly, yes, newcomers to Haskell will probably have difficulty understanding what the type system is telling them, and this will slow them down a bit. But analogously, newcomers to Ruby (especially those using a heavyweight framework) will have difficulty figuring out why their application is doing what it is, and this will slow them down a lot.
(Source: I've worked professionally in both languages.)
For ruby still there would be some topics you need to know about before trying to learn language itself, if you are just starting out.
To be fair, that is not an uncommon situation.
[1] http://snapframework.com/faq#is-anyone-using-snap-in-product...
I have a plugin for Sublime that complains when something is broken, or a dependency is missing. The typesystem is so strong that usually when it compiles, it works.
So my process for refactoring is basically changing typesystems, and having the compiler check my changes until it works again.
Note that this thinks of Ruby as bad only in IDE aspect. Refactoring Ruby is actually quite enjoyable as Ruby is so friendly to unit testing. You just move your code and run your tests again.