7

I can never do too many Haskell tutorials. There is always something to refine and learn. So, I am working through chapter 10 of Real World Haskell, and everything makes sense.

but

Why do

newtype Parse a = Parse { runParse :: ParseState -> Either String (a, ParseState) }

identity :: a -> Parse a
identity a = Parse (\s -> Right (a, s))

getState :: Parse ParseState
getState = Parse (\s -> Right (s, s))

putState :: Parse ()
putState = Parse (\s -> Right ((), s))

Why not simply do

type Parse a = ParseState -> Either String (a, ParseState)

identity :: a -> Parse a
identity a = \s -> Right (a, s)

getState :: Parse ParseState
getState = \s -> Right (s, s)

putState :: Parse ()
putState = \s -> Right ((), s)

In other words, what is the purpose of the wrap and unwrap pattern in here (which I see used in a lot of different places in Haskell)? We get the same Parse Whatever data type, but without the extra indirection.

2 Answers 2

8

The answer is that Haskell doesn't have arbitrary type lambdas, so when we want to eventually make our Parse type an instance of Monad, a newtype is required.

3
  • 2
    Isn't this a case of YAGNI, or at least YAGNIY (You ain't gonna need it yet)? Commented Apr 5, 2013 at 19:43
  • 1
    Thanks! I didn't realize that was the issue. So far as YAGNIY goes, the entire book is pretty questionable in how it presents information, but since monads get involved with almost every major construct, leading in that direction makes some sense. Commented Apr 5, 2013 at 20:13
  • 5
    @RobertHarvey Both monads and applicative functors are used to great effect for parsing. To keep with RWH, chapter 16 uses both styles. Yeah, if you're not gonna support either anyway (RWH ch. 10 apparently doesn't), it's kind of moot. But other examples of this "pattern" (such as State and ErrorT, as OP mentioned in another comment) are monads (or monad transformers, for ErrorT), and instances of numerous other type classes as well, so YANI - You Already Need It.
    – user7043
    Commented Apr 5, 2013 at 21:58
2

It looks like using the notation you're taking issue with is a point of contention. From the comments on that Real World Haskell page:

I'm trying to go through the monad chapter now (chapter 14), and it looks more and more like the parse example in this chapter is somewhat contrived, in that some concepts it presents don't make sense and lead to what looks like needlessly hard-to-understand and complicated code...

and

While newtype and record syntax are explained in chapter 6, here (and for the rest of the book) they're not used for "records", just for what looks like a poor man's substitute for encapsulation. I can't really see why. Isn't the module system provided by Haskell enough for this purpose?

In other words, the answer may well be "don't".

1
  • 2
    Well, same structure is used with State and ErrorT. I assume it's used in a lot of other places. I just don't get why. I think I may try the rest of that chapter without the constructor. Commented Apr 5, 2013 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.