[Haskell] Pattern guards and algebraic datatypes

Graham Klyne GK at ninebynine.org
Fri Jun 18 06:46:20 EDT 2004


At 15:33 17/06/04 -0700, John Meacham wrote:
>I think it was a couple things, Pattern guards were introduced which
>were conceptually a whole lot simpler and provided a way to do many of
>the things views did.
>http://research.microsoft.com/~simonpj/Haskell/guards.html

I like that proposal.

In response to:
[[
Is this a storm in a teacup? Much huff and puff for a seldom-occurring 
situation?  No!  It happens to me ALL THE TIME.  The Glasgow Haskell 
Compiler is absolutely littered with definitions like clunky.

I would really welcome feedback on this proposal.  Have you encountered 
situations in which pattern guards would be useful?  Can you think of ways 
in which they might be harmful, or in which their semantics is non-obvious? 
Are there ways in which the proposal could be improved?  And so on.
]]

I'll say that in my programming, I would find that feature really 
useful.  For example, in my work on Network.URI, I found I had to change 
the underlying data type.  While I don't think this proposal would deal 
with the legacy problem, I do think it would make it easier to define an 
interface that better supports future changes.  I notice some similar 
potential issues with the XML library I'm currently working on:  the 
algebraic data types comprise a considerable part of the package interface, 
which is not always satisfactory.

And a small thought:  a current convenience with algebraic data types is 
the facility to export/import the constructors with (..) notation.  I think 
it would be useful to extend this to accessor functions that are somehow 
bound to the ADT definition.   Hmmm... would this make any sense?:

[[
data URI = URI
     { uriScheme     :: String
     , uriAuthority  :: Maybe URIAuth
     , uriPath       :: String
     , uriQuery      :: String
     , uriFragment   :: String
     } deriving Eq
     where
         scheme (URI {uriScheme=""}) = Nothing
         scheme (URI {uriScheme=a})  = Just a
         :
         etc.
]]

The idea here being that functions declared in the 'where' block would be 
included in any export/import of URI(..).  Then, also, some way to hide the 
individual field labels might also be useful to hide the internal 
structurte from that exposed.

...

The other problem I've noticed with ADTs (which I think has been discussed 
before) is that field labels work like functions to access fields, but 
there's no corresponding mechanism for selective update using the same name.

I could imagine something like:

      scheme :: a -> b -> (a,b)
      scheme a' u@(URI {uriScheme=a}) = (a,u {uriScheme=a'})

with auxiliaries:

      get :: (a -> b -> (a,b)) -> b -> a
      get    f = fst . f undefined
      update :: (a -> b -> (a,b)) -> a -> b -> b
      update f a = snd . f a

hence
      s = get scheme uri
and
      uri' = update scheme s uri

...

#g


------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact



More information about the Haskell mailing list