[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