Explanation of macros; Haskell macros

Dirk Thierbach dthierbach at gmx.de
Fri Oct 31 02:24:11 EST 2003


Coby Beck <cbeck at mercury.bc.ca> wrote:
> 
> "Pascal Costanza" <costanza at web.de> wrote in message
> news:bnscfb$p1k$1 at newsreader2.netcologne.de...
>>

>> I had several cond statements at various places of my code. They
>> all didn't have a default case. At a certain stage, I needed to be
>> sure to get an exceptional return value for the default case
>> instead of NIL. So I added a macro:

Since the overhead of evaluating it at runtime is minimal, especially
with lazyness, that's exactly the situation where it is natural to use
a HOF instead of a macro.

I didn't go through the two proposed Lisp solutions in detail, but here's
a HOF in Haskell that does the same. First a general 'cond' with an
explicit default case, then 'econd' based on cond with an error as
default case:

cond :: a -> [(Bool, a)] -> a
cond def []             = def
cond def ((True,x):_)   = x
cond def ((False,_):xs) = econd xs

econd :: [(Bool, a)] -> a
econd = cond (error "Default econd case")

> CL-USER 91 > (econd
>                ((= 3 4) "foo")
>                ((= 4 4) "bar"))
> "bar"
> 
> CL-USER 92 > (econd
>                ((= 3 4) "foo")
>                ((= 4 5) "bar"))
> 
> Error: fell through ECOND form.  

GHC Interactive, version 5.02.2, for Haskell 98.

Main> econd [(3 == 4, "foo"), (4 == 4, "bar")]
"bar"
Main> econd [(3 == 4, "foo"), (4 == 5, "bar")]
*** Exception: Default econd case


I have made the recursion of 'cond' explicit, but of course 'cond' can
be defined by a fold (and partial application):

cond' = foldr (\(guard,val) def -> if guard then val else def)


You DON'T need macros for such things. You don't need dynamic typing,
either.

- Dirk




More information about the Python-list mailing list