[Haskell-cafe] I'd like start with Haskell, but...

Chris Kuklewicz haskell at list.mightyreason.com
Mon Dec 18 05:37:22 EST 2006


Bulat Ziganshin wrote:
> Hello Waldemar,
> 
> Sunday, December 17, 2006, 2:44:28 AM, you wrote:
> 
>> Maybe, but what is still unclear for me: Haskell is wrong for GUI/Database
>> application because of lack of good libraries or because of it's way of 
>> programming???
> 
> primarily, first. to some degree, second too. Haskell doesn't provide such
> elegant representation of imperative algorithms as imperative languages
> does. just for example, counting sum [1..n]:

I see that "n" is not in an IORef, and for n=1 your loop leaves sum holding 0,
which is just the kind of off-by-1 fencepost but that c excels in generating:

> sum <- newIORef 0
> i <- newIORef 1
> let go = do i' <- readIORef i
>             when (i'<n) $ do
>                 modifyIORef sum (+i')
>                 modifyIORef i   (+1)
>                 go
> result <- readIORef sum
> 
> compare this to C code :)  of course, you can define a lot of
> sugar/combinators that simplify such code but anyway C will be better in
> this area
> 

c code:

int sum(int n) {
  int i = 1;
  int result = 0
  for (; i<=n ; ++i) {
    result += i;
  }
  return result;
}

haskell:

You really want this to be strict, so replace modifyIORef with modifyIORef'

> modifyIORef' r f = do new <- liftM f (readIORef r)
>                       writeIORef r $! new
>                       return new

> s1 n = do
>   sum <- newIORef 0
>   forM_ [1..n] $ \i -> modifyIORef' sum (+i)
>   readIORef sum

As you mentioned, there is easy syntactic sugar definable in Haskell itself:

> a .+=. b = do new <- liftM2 (+) (readIORef a) (readIORef b)
>               writeIORef a $! new
> 
> a .<=. b = liftM2 (<=) (readIORef a) (readIORef b)
> 
> succ_ i = modifyIORef' i succ
> 
> for init test inc block = do
>   init
>   let loop = do proceed <- test
>                 when proceed (block >> inc >> loop)
>   loop

With that sugar it becomes easy to look very much like the c-code:

> s2 n = do
>   sum <- newIORef 0
>   i <- newIORef 1
>   for (return ()) (i .<=. n) (succ_ i)
>       (sum .+=. i)
>   readIORef sum

And we do have "postfix" operators with the latest GHC:

> (.++) a = do old <- readIORef a
>              writeIORef a $! succ old
>              return old



More information about the Haskell-Cafe mailing list