Friday, July 2, 2010

Quick note on imports


    import m.f; -- f must have only a single component
    import module m.n; -- n must have only a single component
    import type m.t; -- t must have only a single component
    import m.(..); -- import everything
    import m.(names); -- import certain names with a single declaration
    import m.(..\names); -- import all but certain names
To do this we basically want a way to say 'gimme a name provided it is not followed by a period' which we can probably do since it needs to be followed by a semicolon instead. We can parse the other cases pretty simply.

Thursday, July 1, 2010

Haskell Package Review: regex-posix

The 15th most popular Haskell library is regex-posix. This library is an official component of the Haskell Platform, and is part of the "batteries included" concept. The following commentary is based primarily on its Haddock documentation; links are provided. regex-posix exports six modules:
  • Text.Regex.Posix — directly exports only one symbol, a constant. Also re-exports instances from the remainder fo the package.
  • Text.Regex.Posix.ByteString — Exports four data types (including newtypes), three type synonyms, nine constants, and three functions, all in the IO monad; acocrding to the documentation, it also provides orphan instances for two type classes, RegexLike and RegexMaker, provided by the regex-base package.
  • Text.Regex.Posix.ByteString.Lazy — Exports exactly the same API as the previous package, but with different orphan instances.
  • Text.Regex.Posix.Sequence — Exports exactly the same API as the previous package, but with different orphan instances.
  • Text.Regex.Posix.String — Exports exactly the same API as the previous package, but with different orphan instances.
  • Text.Regex.Posix.Wrap — Exports four data types (including newtypes), three type synonyms, 21 constants, five functions in the IO monad, one constrained polymorphic function returning a simple value, and one constrained polymorphic function returning a value in an arbitrary monad.
So, in total, the library provides (including duplicates in multiple modules' export lists) 20 data types, 15 type synonyms, 58 constants, 17 functions in the IO monad, one constrained polymorphic function returning a simple value, and one constrained polymorphic function returning a value in an arbitrary monad. A necessary condition for a function to be a combinator is that it have at least one argument of the same type as its result. Of the functions directly exported by this library, only four come close to satisfying this criterion: the four modules with nearly identical signatures all export a function

    regexec :: Regex -> string -> IO (Either WrapError (Maybe (string, string, string, [string])))
for different types string. However, in fact, these functions are not combinators, for the following reasons:
  • The argument is of type string; the result is not. The result strings are in fact nested in a mult-result return wrapped inside three monads.
  • All three monads involved are exception monads, meaning that attempting to un-pack the result of a regexec call may fail to produce any string values at all.
  • The string values returned, if any, are shorter and simpler than the input.
All of these characteristics are decidedly un-combinatorial in nature. The possibility remains that the instances exported by this package include one or more combinators as methods. Since the classes these instances implement are defined by the regex-base package, which these reviews will be reaching in a few days, we defer consideration to the review of that package. In the meantime, we can conclude that there is no evidence that this library is written in a combinatorial, rather than imperative, style.