Intro to Haskell article (first draft)

This commit is contained in:
Tony Hannan 2011-07-14 18:47:14 -04:00
parent 25a827a46c
commit acb0d62aa2
3 changed files with 31 additions and 11 deletions

View file

@ -203,7 +203,7 @@ dBits = bitOr . map dBit
-- ** Request -- ** Request
-- | A request is a message that is sent with a 'Reply' returned -- | A request is a message that is sent with a 'Reply' expected in return
data Request = data Request =
Query { Query {
qOptions :: [QueryOption], qOptions :: [QueryOption],

View file

@ -4,7 +4,7 @@
module Database.MongoDB.Query ( module Database.MongoDB.Query (
-- * Monad -- * Monad
Action, access, Failure(..), Action, access, Failure(..), ErrorCode,
AccessMode(..), GetLastError, master, slaveOk, accessMode, AccessMode(..), GetLastError, master, slaveOk, accessMode,
MonadDB(..), MonadDB(..),
-- * Database -- * Database
@ -85,19 +85,19 @@ instance Error Failure where strMsg = error
-- | Type of reads and writes to perform -- | Type of reads and writes to perform
data AccessMode = data AccessMode =
ReadStaleOk -- Read-only action, reading stale data from a slave is OK. ReadStaleOk -- ^ Read-only action, reading stale data from a slave is OK.
| UnconfirmedWrites -- Read-write action, slave not OK, every write is fire & forget. | UnconfirmedWrites -- ^ Read-write action, slave not OK, every write is fire & forget.
| ConfirmWrites GetLastError -- Read-write action, slave not OK, every write is confirmed with getLastError. | ConfirmWrites GetLastError -- ^ Read-write action, slave not OK, every write is confirmed with getLastError.
type GetLastError = Document type GetLastError = Document
-- ^ Parameters for getLastError command. For example ["w" =: 2] tells the server to wait for the write to reach at least two servers in replica set before acknowledging. See "http://www.mongodb.org/display/DOCS/Last+Error+Commands" for more options. -- ^ Parameters for getLastError command. For example @[\"w\" =: 2]@ tells the server to wait for the write to reach at least two servers in replica set before acknowledging. See <http://www.mongodb.org/display/DOCS/Last+Error+Commands> for more options.
master :: AccessMode master :: AccessMode
-- ^ @'ConfirmWrites' []@ -- ^ Same as 'ConfirmWrites' []
master = ConfirmWrites [] master = ConfirmWrites []
slaveOk :: AccessMode slaveOk :: AccessMode
-- ^ @'ReadStaleOk'@ -- ^ Same as 'ReadStaleOk'
slaveOk = ReadStaleOk slaveOk = ReadStaleOk
accessMode :: (Monad m) => AccessMode -> Action m a -> Action m a accessMode :: (Monad m) => AccessMode -> Action m a -> Action m a
@ -208,7 +208,7 @@ data Selection = Select {selector :: Selector, coll :: Collection} deriving (Sh
-- ^ Selects documents in collection that match selector -- ^ Selects documents in collection that match selector
type Selector = Document type Selector = Document
-- ^ Filter for a query, analogous to the where clause in SQL. @[]@ matches all documents in collection. @[x =: a, y =: b]@ is analogous to @where x = a and y = b@ in SQL. See <http://www.mongodb.org/display/DOCS/Querying> for full selector syntax. -- ^ Filter for a query, analogous to the where clause in SQL. @[]@ matches all documents in collection. @[\"x\" =: a, \"y\" =: b]@ is analogous to @where x = a and y = b@ in SQL. See <http://www.mongodb.org/display/DOCS/Querying> for full selector syntax.
whereJS :: Selector -> Javascript -> Selector whereJS :: Selector -> Javascript -> Selector
-- ^ Add Javascript predicate to selector, in which case a document must match both selector and predicate -- ^ Add Javascript predicate to selector, in which case a document must match both selector and predicate
@ -342,13 +342,13 @@ data Query = Query {
} deriving (Show, Eq) } deriving (Show, Eq)
type Projector = Document type Projector = Document
-- ^ Fields to return, analogous to the select clause in SQL. @[]@ means return whole document (analogous to * in SQL). @[x =: 1, y =: 1]@ means return only @x@ and @y@ fields of each document. @[x =: 0]@ means return all fields except @x@. -- ^ Fields to return, analogous to the select clause in SQL. @[]@ means return whole document (analogous to * in SQL). @[\"x\" =: 1, \"y\" =: 1]@ means return only @x@ and @y@ fields of each document. @[\"x\" =: 0]@ means return all fields except @x@.
type Limit = Word32 type Limit = Word32
-- ^ Maximum number of documents to return, i.e. cursor will close after iterating over this number of documents. 0 means no limit. -- ^ Maximum number of documents to return, i.e. cursor will close after iterating over this number of documents. 0 means no limit.
type Order = Document type Order = Document
-- ^ Fields to sort by. Each one is associated with 1 or -1. Eg. @[x =: 1, y =: -1]@ means sort by @x@ ascending then @y@ descending -- ^ Fields to sort by. Each one is associated with 1 or -1. Eg. @[\"x\" =: 1, \"y\" =: -1]@ means sort by @x@ ascending then @y@ descending
type BatchSize = Word32 type BatchSize = Word32
-- ^ The number of document to return in each batch response from the server. 0 means use Mongo default. -- ^ The number of document to return in each batch response from the server. 0 means use Mongo default.

20
doc/Article2.md Normal file
View file

@ -0,0 +1,20 @@
Type class may use result type as descriminator.
Null pointer exceptions caught at compile time.
Intro to Haskell
There are already plenty of languages to write your Mongo application in, so why would you consider [Haskell](http://www.haskell.org/)? The reason is there are several unique features in Haskell that help reduce bugs and increase programmer productivity (and serenity). In this article, I will introduce some of these features and describe how they could benefit your Mongo application. I will also discuss one disadvantage of Haskell that you should watch out for.
But first let me address probably the most common reason why Haskell is not considered: because no one you know is using it, i.e. it is not popular. My rebuttal to this is: even though Haskell is not popular, it is popular *enough*. The community and ecosystem (libraries and tools) has reached a critical mass such that you can easily find previous success stories (see [Haskell in industry](http://haskell.org/haskellwiki/Haskell_in_industry)), find Haskell programmers to hire (just send an email to the [Haskell mailing list](http://www.haskell.org/haskellwiki/Mailing_Lists)) and find libraries for most anything you would expect to find in a popular language (see [Hackage](http://hackage.haskell.org/packages/archive/pkg-list.html) for the list of libraries). So I think it is incorrect to reject Haskell for this reason. Assuming you agree that Haskell is a *mainstream* language by this definition of critical mass (or popular enough), we can now judge Haskell on its features alone.
I think the most distinguishing feature of Haskell is [declared effects](http://en.wikipedia.org/wiki/Effect_system). No other mainstream language has it. Declared effects means the type of a procedure includes the type of side effect it may have (in addition to the type of value it will return). This means that just by looking at a procedure's type you know what effect it may have, without having to remember or look at its code. Plus the compiler checks that the code does not violate its declared effect, which helps a lot with maintenance.
Another nice feature of Haskell is the elimination of null pointer exceptions. A possibly null value is declared as such, and you cannot get its non-null value without first checking for null. The compiler enforces this so it is impossible to get a null pointer exception at runtime.
Higher-order functions and currying makes it easy to code at a higher level. For example, you rarely need a for loop, because you use higher level operations instead like, map, filter, and fold.
[Type inference](http://en.wikipedia.org/wiki/Type_inference) makes code succint and thus easier to read and write.