[Haskell-cafe] [ANNOUNCE] Penny - double-entry accounting

2013-10-02 Thread Omari Norman
I'm pleased to make the first public announcement of the availability of
Penny, a double-entry command-line accounting system.

Penny is inspired by Ledger, an excellent program in its own right.
Ledger's websites and sales pitches are much better developed than those
for Penny, so first take a look at Ledger's website to see if the concepts
behind this program interest you:

http://www.ledger-cli.org/

With that in mind, here is what distinguishes Penny from Ledger:

* Smarter report formatting. When using Ledger I rarely bothered to
reformat the reports because I could never remember how to use the cryptic
formatting strings.  Penny automatically formats reports to fit the width
of your screen.  You can easily add or remove information in your reports.

* Use of color.  Color is baked into Penny, making reports easier to read.
It takes advantage of 256-color terminals where available.

* Adherence to double-entry accounting principles.  Ledger will allow you
to enter unbalanced transactions.  Penny never allows this.  Even
infinitesimally unbalanced transactions will render your entire ledger
invalid.

* Different handling of commodities.  In part because of the strict
adherence to double-entry accounting principles, Penny handles commodities
(e.g. transactions involving multiple currencies, or currency and equities)
differently than Ledger.  Some might regard Penny's handling of commodities
to be a pain, but I think it results in a system that is more predictable,
has no corner cases, and is easy to test.

* More orthogonal command-line interface.  For example, in Ledger, you use
one set of options to filter postings by date, and a different set of
options to control the dates of postings that are shown in the register
report.  Penny uses identical options for these two purposes; what these
options mean depends on where they appear on the command line.  In
addition, in Penny you can build filtering expressions of arbitrary
complexity, using either infix or reverse polish notation.

* Automated import of postings.  You can import postings from your bank as
long as it gives you OFX files. Many financial institutions supply OFX
files, as it is the format used by Quicken and by the now-defunct Microsoft
Money.  Penny can also help automate a great deal of the process of
reconciling your ledger with bank statements.  This removes an enormous
amount of the drudgery that is associated with maintaining a ledger.

* Exposes a Haskell API.  This is actually the primary reason I wrote
Penny.  I run several automated checks on my ledger.  Doing this in Ledger
was growing difficult because I had no standalone parser for the ledger
files.  With Penny I can easily write additional small programs to check up
on the consistency of my ledger (for instance, to make sure I'm not using
invalid accounts, or to make sure that a particular account has postings
within a given time period.)  The power of Haskell makes this much easier
than it would be if I used a dynamically typed language like Haskell or, as
I used to do with Ledger, a random assemblage of shell, Awk scripts,
Haskell, and more.

Another child of Ledger that is written in Haskell is hledger:

http://hledger.org/

hledger is a great program; if you like it, please continue using it.  In
addition to what you can glean from the bullets above, here are some key
ways Penny differs from hledger:

* hledger is at least partially compatible with Ledger; Penny is
incompatible with Ledger.  There currently is no program to convert Ledger
files to the format Penny uses (I once wrote such a program to convert my
Ledger files to Penny; after that the program was of no use to me and the
file format has since changed, rendering that code useless.)

* hledger has a web interface.  Penny does not and I doubt it ever will.

* hledger has a robust community; Penny does not.

* hledger supports more of Ledger's feature set with features such as
timelog support, periodic reports, and balance assertions.  Penny does not
have these features.

* hledger uses floating-point types to represent amounts:

http://hackage.haskell.org/package/hledger-lib-0.21.3/docs/Hledger-Data-Types.html#t:Quantity

Penny uses only integers:

http://hackage.haskell.org/package/penny-0.30.0.0/docs/Penny-Lincoln-Bits-Qty.html

This page summarizes why that matters:

http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency

* Penny is BSD3; hledger is GPL.

And an entirely subjective comparison that may be biased: Penny is designed
from the ground up to use Haskell's static type system and its module
system to its maximum advantage, which makes Penny easier to use as a base
for your own programs to check your ledger, and which reduces bugs.

Penny has been in development for over a year now, and I use it to maintain
my financial records.  A set of QuickCheck tests, in conjunction with
maximum exploitation of Haskell's static type system, help ensure the
correctness of the 

Re: [Haskell-cafe] On Markdown in Haddock and why it's not going to happen

2013-08-31 Thread Omari Norman
On Thu, Aug 29, 2013 at 9:30 PM, Mateusz Kowalczyk
fuuze...@fuuzetsu.co.ukwrote:

 Greetings café,

 Perhaps some saddening news for Markdown fans out there. As you might
 remember, there was a fair amount of push for having Markdown as an
 alternate syntax for Haddock.


This is a little off-topic, but the Haddock website apparently is years out
of date.

http://www.haskell.org/haddock/

says the latest version is 2.8.0 released in September 2010, but apparently
I have 2.13.2 on my machine.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] loop error message

2013-06-21 Thread Omari Norman
I compiled some code with GHC 7.6.3 that produces a simple error at runtime

myProgramName: loop

At which point the program exits with code 1.

Is there documentation for this error anywhere? Does it mean I have some
infinite loop in my code somewhere? If so, does GHC catch all infinite
loops? I have never gotten this error before. Thanks.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] [ANNOUNCE] rainbow - print colored text on UNIX-like systems

2013-06-09 Thread Omari Norman
Hi all,

rainbow is a simple package to help you print colored text on UNIX-like
systems. It's different from packages like terminfo (upon which it is
based) and ansi-terminal in two ways. First, rainbow assumes you print text
one chunk at a time. The properties of the terminal are reset with every
chunk. That way you do not need to remember what the terminal's properties
were before you print a new chunk. One chunk does not affect the next
chunk. It's a state-free model that fits in well with functional
programming.

Second, rainbow makes it easy to use both 8- and 256-color terminals.

Some sample things you can do in ghci:

:set -XOverloadedStrings
:m +System.Console.Rainbow
putChunkLn $ Hello bold green world!  f_green  bold
putChunkLn $ Red on 8-color, pink on 256-color  f_red  c256_f_201
mapM_ putChunk [green on blue  f_green  b_blue,  , blue on green
 f_blue  b_green, \n]

So, add some color to things:

http://hackage.haskell.org/package/rainbow
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Safe Haskell safe-inferred status

2012-12-08 Thread Omari Norman
Is there a way to determine whether a module has been marked safe by GHC
for purposes of Safe Haskell?

The GHC 7.4 docs say that if I compile a module and I don't use the -XSafe
or -XTrustworthy flag, GHC will automatically figure out whether the module
would have compiled with -XSafe and, if so, marks the module as safe. Where
does GHC record this determination? It doesn't seem to show up in ghc-pkg
dump (there you can see trusted packages, but I am looking for
safe-inferred status for modules.) ghc --show-iface seems to come up dry
too.

I know Haddock shows this information but sometimes it says Safe Haskell:
None. I have no idea what this means so I was wondering what GHC itself
says.

Thanks. --Omari
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] cabal equivalent to make -k?

2012-07-06 Thread Omari Norman
When using make (or, at least, GNU make) the -k option keeps going
as far as possible after a compilation error. It's handy during
developing--for instance, I know half of my code is busted, but I
just want to see if this file compiles. Is there a similar way to do
this with cabal? Thanks. --Omari

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Alex character sets

2012-03-24 Thread Omari Norman
I'm wrinting (or at least, trying to write) an Alex lexer. Say I want to
group character ranges together and specify that I want a character that is
*not* in any of those ranges. Example

---

 {
module Main where
}

%wrapper posn-bytestring

$lowAscii = \x00-\x1f -- unprintable stuff
$lowSymbol = \x21-\x2f -- exclamation point to solidus
$space = \x20

$special = [^$lowAscii $lowSymbol]

lex :-

$special { Word }

{
data Token = Word AlexPosn ByteString.ByteString
}

When I run this through Alex, I get Prelude.Enum.Char.pred: bad argument.

What am I doing wrong? How would I accomplish this sort of thing? Thanks.
--Omari
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Alex character sets

2012-03-24 Thread Omari Norman
OK, it turns out that having [^\x00] as a character range gives me the
error with pred. [\x00] works fine; [^\x00] gives the error message.

On Sat, Mar 24, 2012 at 6:33 PM, Omari Norman om...@smileystation.comwrote:

 I'm wrinting (or at least, trying to write) an Alex lexer. Say I want to
 group character ranges together and specify that I want a character that is
 *not* in any of those ranges. Example

 ---

  {
 module Main where
 }

 %wrapper posn-bytestring

 $lowAscii = \x00-\x1f -- unprintable stuff
 $lowSymbol = \x21-\x2f -- exclamation point to solidus
 $space = \x20

 $special = [^$lowAscii $lowSymbol]

 lex :-

 $special { Word }

 {
 data Token = Word AlexPosn ByteString.ByteString
 }

 When I run this through Alex, I get Prelude.Enum.Char.pred: bad argument.

 What am I doing wrong? How would I accomplish this sort of thing? Thanks.
 --Omari

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Impact of try on Parsec performance

2012-03-02 Thread Omari Norman
The Parsec documentation says that Parsec performs best on predictive
grammars, and Parsec does not backtrack by default to improve performance
(though this also improves error messages).

On the other hand, I notice that attoparsec and polyparse backtrack by
default, and attoparsec claims to be faster than Parsec (I can't remember
if polyparse makes this claim).

The Parsec documentation says there is a penalty for using try and suggests
left-factoring grammars when possible. Real World Haskell says that
excessive use of try can degrade Parsec performance quite significantly. On
the other hand, some of the combinators provided with Parsec, such as
notFollowedBy, use try.

So my question is: what is the practical impact of using try? I ask because
as a novice I have a simple grammar that could, perhaps, be factored to
avoid use of try, but it's quite a brain puzzle for me and I wonder if it
would ever be worth it. Does it matter how many characters try would have
to store, or how often it would run?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] [Haskell] ANNOUNCE multiarg - parser combinators for command line parsing

2012-01-30 Thread Omari Norman
On Mon, Jan 30, 2012 at 03:19:47PM +0100, Henning Thielemann wrote:
 
 On Sun, 29 Jan 2012, Simon Meier wrote:
 
 I'm currently using Neil Mitchell's cmdargs package [1]. How does your
 package compare to that?
 
 Last time I checked cmdargs it was not referential transparent. Is
 multiarg better in this respect?
 

Absolutely, multiarg is 100% referentially transparent.

The main data type in multiarg is a monad transformer, so if the
programmer really wants to write something that does IO or is otherwise
not referentially transparent, then she can. Certainly there is no need
to do this though. I'd expect one would usually put the transformer on
top of Identity, as I have always done so far. But the option is there
if you want it. --Omari


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Text.Regex.Base throws exceptions with makeRegexOptsM

2011-12-29 Thread Omari Norman
Hi folks,

I'm using Text.Regex.Base with the TDFA and PCRE backends. I want to
compile regular expressions first and make sure the patterns were
actually valid, so I used makeRegexOptsM, which indicates a bad regular
expression by calling fail. That allows you to use makeRegexOptsM with
Maybe or with (Either String) (assuming that Either String is an
instance of Monad, which of course is defined in Control.Monad.Error.)

Doing this with Maybe Regex works like it should--bad pattern gives you
a Nothing. But if you want to see the error message by using Either
String, an exception gets thrown with the bad pattern, rather than
getting a Left String.

Why is this? Seems like an odd bug somewhere. I am a Haskell novice, but
I looked at the code for Text.Regex.Base and for the TDFA and PCRE
backends and there's nothing in there to suggest this kind of
behavior--it should work with Either String.

The attached code snippet demonstrates the problem. I'm on GHC 7.0.3
(though I also got the problem with 6.12.3) and regex-base-0.93.2 and
regex-tdfa-1.1.8 and regex-pcre-0.94.2. Thanks very much for any tips or
ideas. --Omari
module Main where

import Text.Regex.Base.RegexLike
import Text.Regex.TDFA.String
import Control.Monad.Error

badPattern = [unclosed brace

main = do
  let maybeRegex =
makeRegexOptsM defaultCompOpt
defaultExecOpt badPattern :: Maybe Regex

  -- This outputs Bad, no regex, as expected
  putStrLn $ maybe Good regex
(const Bad, no regex) maybeRegex

  let eitherRegex =
makeRegexOptsM defaultCompOpt
defaultExecOpt badPattern :: Either String Regex
  
  -- This throws an exception, why? The whole point of
  -- using makeRegexOptsM is to not have exceptions.
  putStrLn $ either show (const Good regex) eitherRegex
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Text.Regex.Base throws exceptions with makeRegexOptsM

2011-12-29 Thread Omari Norman
On Fri, Dec 30, 2011 at 01:24:02AM +0100, Daniel Fischer wrote:
 For Either, there used to be
 
 instance Error e = Monad (Either e) where
 ...
 fail s = Left (strMsg s)
 
 in mtl's Control.Monad.error, and all was fine if one used the regex 
 functions with e.g. (Either String) as the Monad.
 
 Recently, however, it was decided to have
 
 instance Monad (Either e) where
 ...
 fail s = error s -- not explicitly, but by Monad's default method
 
 in Control.Monad.Instances. So now, if you have a pattern-match failure 
 using (Either String), you don't get a nice 'Left message' but an error.

Thanks so much, I would never have figured all this out. Spent a lot of
time tonight rummaging through mtl and transformers and
Control.Monad.Instances.

 Now, what can you do to get the equivalent of the old (Either String)?
 
 Use 'ErrorT String Identity'.

This I tried. It turned out that it didn't work though and I had the
same problem. I am guessing it is because my module has some imports at
the top that are bringing the instances in Control.Monad.Instances into
scope. Then it seems the Monad instance in Control.Monad.Instances
(which is using the default fail, which calls error) is being used,
rather than the instance from Control.Monad.Trans.Error. Only now do I
really understand why orphan instances are bad:

http://www.haskell.org/haskellwiki/Orphan_instance

A simple fix for it all was to wrap Either in a newtype and then define
a Monad instance for the newtype. --Omari


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Haddock docs don't list instances

2011-01-06 Thread Omari Norman
Web versions of Haddock documentation, even this old one, list a class's
instances.

http://www.haskell.org/ghc/docs/6.2.2/html/libraries/base/Prelude.html#5

My Haddock documentation does not have any class instances at all. This
is true both of the documentation that comes with my Linux system (I use
Debian) and of the documentation I generate locally using cabal-install
or the Setup.hs program in my homemade packages.

How do I get Haddock to make the instance lists? Anybody else have this
problem--maybe it is a Debian bug? Thanks. --Omari

-- 
Pay a little now, or pay a lot later.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Why is toRational a method of Real?

2010-08-04 Thread Omari Norman
Why is toRational a method of Real? I thought that real numbers need not
be rational, such as the square root of two. Wouldn't it make more sense
to have some sort of Rational typeclass with this method? Thanks.
--Omari

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Regex multiple matches

2010-07-20 Thread Omari Norman
Hi,

How do I use Text.Regex.PCRE to get information on multiple matches? For
instance, in ghci I get this error message:

Prelude Text.Regex.PCRE foo =~ o :: [(Int,Int)]

interactive:1:0:
No instance for (RegexContext Regex [Char] [(Int, Int)])
  arising from a use of `=~' at interactive:1:0-11
Possible fix:
  add an instance declaration for
  (RegexContext Regex [Char] [(Int, Int)])
In the expression: foo =~ o :: [(Int, Int)]
In the definition of `it': it = foo =~ o :: [(Int, Int)]

Real World Haskell's text suggests this should work, but the ghci
output is littered with errors.

http://book.realworldhaskell.org/read/efficient-file-processing-regular-expressions-and-file-name-matching.html

Thanks for any help.
Omari
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Regex multiple matches

2010-07-20 Thread Omari Norman
 How do I use Text.Regex.PCRE to get information on multiple matches? For
 instance, in ghci I get this error message:
 
 Prelude Text.Regex.PCRE foo =~ o :: [(Int,Int)]

Solved; do

getAllMatches (foo =~ o) :: [(Int, Int)]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe