par
is declared as:
par :: a -> b -> b
Notice, that argument one is thrown away. In order to use par you need to play tricks like using the same expression multiple times.
If its purpose is to execute a and b in parallel, why wasn't it defined like this?:
par :: (a, b) -> (a, b)
Taking a tuple of (unevaluated) expressions and returning the same expressions - while they are potentially being materialized on background threads.
It seems the latter model is simpler than the former. Why was the design chosen that way?
Learning Haskell Programming Language means you need to think in a functional manner. Many new programming languages allow the functional style of programming, but most developers do not make full usage of these features since they think in a more of object-oriented pattern, the reason being their background comes from learning C or C++.
In addition, Haskell generates a warning if you are missing cases in your pattern matching. In the getFirst example, if we forgot to handle the empty list case, the compiler would warn us. Without pattern matching, no warning would be issued, and the bug could be left undetected.
You’ve learned ideas such as referential transparency, lazy evaluation, and pattern-matching in Haskell. You’ve also seen that recursion is used instead of for-loops, and it can make code a lot more concise.
Since the syntax is more compact than an if-statements, your code becomes easier to read. In addition, Haskell generates a warning if you are missing cases in your pattern matching. In the getFirst example, if we forgot to handle the empty list case, the compiler would warn us.
In the former, you can easily spark more than two computations,
c1 `par` c2 `par` c3 `par` c4 `pseq` something c1 c2 c3 c4
which would be rather cumbersome in the latter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With