Saturday, September 22, 2012

A quick look at Haskell Views

Haskell views is a language extension that allows calling functions as part of the pattern matching process. A simple example looks like this:

square x = x*x

doSomething :: Integer -> Integer -> Integer
doSomething (square -> squared) other = squared + other

The real power of this feature is that you can combine it with other pattern matching elements. For example, in the following code the 'rgroups' function is used to match a regular expression and return a list with the groups resulting of this matching process. This function is used as part of the 'classify' function.

rgroups :: String -> String -> [String]
rgroups regex text = result
     matchResult :: (String, String, String, [String])
     matchResult = text =~ regex
     (_, _, _, result) = matchResult

data Record =
  Person String Integer
  | Company String
  | Unknown String
 deriving Show

classify  ((rgroups "([a-z]*):[ ]*([a-z]*)[ ]*([0-9]+)") -> ["person", personName, age]) =
  Person personName (read age)
classify  ((rgroups "([a-z]*):[ ]*([a-z]*)") -> ["company", personName]) =
  Company personName
classify line =
  Unknown line

We can use this function as follows:

txtlines = ["company:  testcomp",
            "person: someone    30",
            "person:another    40"]

*Main>  map classify txtlines
[Company "testcomp",Person "someone" 30,Unknown "oasd",Person "another" 40]

Since this is a language extension we need to activate it by using a GHC command line argument or by adding the following code at the top of the file.

{-# LANGUAGE ViewPatterns #-}

More information can be found in the ViewPatterns section of the GHC wiki. This feature is an inspiration for the Scala extractors and F# active patterns which I talked about in previous posts.