Greg Buchholz | 1 Jun 2006 02:22

Tips for converting Prolog to typeclasses?

    Lately, in my quest to get a better understanding of the typeclass
system, I've been writing my typeclass instance declarations in Prolog
first, then when I've debugged them, I port them over back over to
Haskell.  The porting process involves a lot trial and error on my part
trying to decide when to use functional dependencies and which compiler
extension to enable ( -fallow-undecidable-instances,
-fallow-overlapping-instances, etc.).  Which might be okay, but I still
can produce things that won't compile, and I don't necessarily know if
I'm making a fundamental mistake in a program, or if there's something
trivial that I'm not doing quite right.

    For example, there was a question on haskell-cafe last week about
creating an "apply" function.  My first solution (
http://www.haskell.org//pipermail/haskell-cafe/2006-May/015905.html )
was to use type classes and nested tuples for the collection of
arguments.  This works fine.  But then I wanted to try to get closer to
what the original poster wanted, namely to use regular homogenous lists
to store the arguments.  So I thought I could reuse the class definition
and just provide new instances for a list type, instead of the nested
tuple type.  Here's the class definition...

> class Apply a b c | a b -> c where
>     apply :: a -> b -> c

...So I wrote the following Prolog snippets which seemed like they might
properly describe the situation I was looking for...

:- op(1000,xfy,=>).  % use => instead of -> for arrow type
app(A=>B,[A],C) :- app(B,[A],C).
app(C,[A],C).
(Continue reading)

Robert Dockins | 1 Jun 2006 02:59

Re: Tips for converting Prolog to typeclasses?

On Wednesday 31 May 2006 08:22 pm, Greg Buchholz wrote:
>     Lately, in my quest to get a better understanding of the typeclass
> system, I've been writing my typeclass instance declarations in Prolog
> first, then when I've debugged them, I port them over back over to
> Haskell.  The porting process involves a lot trial and error on my part
> trying to decide when to use functional dependencies and which compiler
> extension to enable ( -fallow-undecidable-instances,
> -fallow-overlapping-instances, etc.).  Which might be okay, but I still
> can produce things that won't compile, and I don't necessarily know if
> I'm making a fundamental mistake in a program, or if there's something
> trivial that I'm not doing quite right.
>
>     For example, there was a question on haskell-cafe last week about
> creating an "apply" function.  My first solution (
> http://www.haskell.org//pipermail/haskell-cafe/2006-May/015905.html )
> was to use type classes and nested tuples for the collection of
> arguments.  This works fine.  But then I wanted to try to get closer to
> what the original poster wanted, namely to use regular homogenous lists
> to store the arguments.  So I thought I could reuse the class definition
> and just provide new instances for a list type, instead of the nested
> tuple type.  Here's the class definition...
>
> > class Apply a b c | a b -> c where
> >     apply :: a -> b -> c
>
> ...So I wrote the following Prolog snippets which seemed like they might
> properly describe the situation I was looking for...
>
> :- op(1000,xfy,=>).  % use => instead of -> for arrow type
>
(Continue reading)

Christophe Poucet | 1 Jun 2006 04:59
Picon

Filtering on data constructors with TH

Dear,

After having read Bulat's mail regarding TH when I had mentioned my wish 
for Pretty, I decided to use TH for a much smaller project. That's why 
today I have created an automated derivation for data constructor 
filtering. As I started coding someone mentioned that something similar 
can be done with list comprehensions, so I'm not certain about the scope 
of usefulness, however personally I have found the need for this at 
times. Anyways, the code can be obtained from the darcs repo at
http://oasis.yi.org:8080/repos/haskell/filter

Suggestions, bugs, additions are always welcome :)

Here is an example:

{-# OPTIONS_GHC -fglasgow-exts -fth #-}
module Main where

import Filter 

data T = A Int String | B Integer | C deriving Show

data Plop a b = Foo a | Bar b deriving Show

$(deriveFilter ''T)
$(deriveFilter ''Plop)

main :: IO ()
main = do
  let l = [A 1 "s", B 2, C] 
(Continue reading)

Thomas Hallgren | 1 Jun 2006 08:05
Picon

Re: Editors for Haskell

Brian Hulley wrote:

> 
> Another thing which causes difficulty is the use of qualified operators, 
> and the fact that the qualification syntax is in the context free 
> grammar instead of being kept in the lexical syntax (where I think it 
> belongs).

You are in luck, because according to the Haskell 98 Report, qualified 
names are in the lexical syntax!

	http://www.haskell.org/onlinereport/syntax-iso.html

So, C.f is a qualified name, but C . f is composition of the Constructor 
C with the function f.

--
Thomas H
Brian Hulley | 1 Jun 2006 09:48

Re: Editors for Haskell

Thomas Hallgren wrote:
> Brian Hulley wrote:
>
>>
>> Another thing which causes difficulty is the use of qualified
>> operators, and the fact that the qualification syntax is in the
>> context free grammar instead of being kept in the lexical syntax
>> (where I think it belongs).
>
> You are in luck, because according to the Haskell 98 Report, qualified
> names are in the lexical syntax!
>
> http://www.haskell.org/onlinereport/syntax-iso.html
>
> So, C.f is a qualified name, but C . f is composition of the
> Constructor C with the function f.

Thanks for pointing this out. Although there is still a problem with the 
fact that var, qvar, qcon etc is in the context free syntax instead of the 
lexical syntax so you could write:

        2 `    plus      ` 4
        (    Prelude.+
               {- a comment -} ) 5 6

I think this must have been what was in the back of my mind. To make parsing 
operator expressions simple (ie LL1), it is necessary to somehow treat ` 
plus    ` as a single lexeme, but by having such a thing in the CFG instead 
of the lexical grammar, a "lexeme" can then occuply multiple lines (which 
means you can't associate each line with a list of lexemes for incremental 
(Continue reading)

Bulat Ziganshin | 1 Jun 2006 07:39
Picon

Re: Filtering on data constructors with TH

Hello Christophe,

Thursday, June 1, 2006, 6:59:56 AM, you wrote:

> data Plop a b = Foo a | Bar b deriving Show
>   print $ filter isFoo l2

btw, DrIFT already have modules what implements this, along with
many other. it's a list of basic rules included in DrIFT:

standardRules = [("test",dattest, "Utility", "output raw data for testing", Nothing),
                  ("update",updatefn, "Utility","for label 'foo' provides 'foo_u' to update it and foo_s to set it",
Nothing ),
                  ("is",isfn, "Utility", "provides isFoo for each constructor", Nothing),
                  ("get",getfn, "Utility", "for label 'foo' provide foo_g to get it", Nothing),
                  ("from",fromfn, "Utility", "provides fromFoo for each constructor", Nothing),
                  ("has",hasfn, "Utility", "hasfoo for record types", Nothing),
                  ("un",unfn, "Utility", "provides unFoo for unary constructors", Nothing),
                  ("NFData",nffn, "General","provides 'rnf' to reduce to normal form (deepSeq)", Nothing ),
                  ("Eq",eqfn, "Prelude","", Nothing),
                  ("Ord",ordfn, "Prelude", "", Nothing),
                  ("Enum",enumfn, "Prelude", "", Nothing),
                  ("Show",showfn, "Prelude", "", Nothing),
                  ("Read",readfn, "Prelude", "", Nothing),
                  ("Bounded",boundedfn, "Prelude", "", Nothing)]

--

-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin <at> gmail.com
(Continue reading)

Bulat Ziganshin | 1 Jun 2006 10:37
Picon

sum-file shootout test

Hello Haskell-cafe,

i have analyzed performance of various sum-file implementations (see
http://shootout.alioth.debian.org/debian/benchmark.php?test=sumcol&lang=all )

first, one-liner implementation (attached as b.hs) works about 500
seconds on my cpu. it can be made 10x faster just by using it's own
'read' procedure (c.hs). this tells us that current 'read' implementation
in GHC is VERY SLOW.

next step to make things go faster you can see at
http://shootout.alioth.debian.org/debian/benchmark.php?test=sumcol&lang=ghc&id=4
- now it's the fastest GHC entry on this test. speedup is a result of
throwing away all the lines/map/read/sum individual procedures and
writing entire algorithm over the plain stream of Chars. this allows
us to omit all the construction/deconstruction of lazy boxes, so this
program works about 10 seconds on my box.

now the main problem is getContents itself, which uses about 70% of
total time, because it requires to construct/deconstruct lazy box for
each Char read. Using Streams library, we can omit this work and use
straightforward imperative code (h.hs). this program works 4 times
faster (2.8 seconds) than faster Haskell variant, what should be about
1.5 times faster than today's fastest (D Digital Mars) entry in this
test

i think that close speed can be also obtained by using line-oriented
I/O in Streams+ByteString combination and then applying some
"readInt :: ByteString -> Int" conversion while compiling under GHC 6.5

(Continue reading)

Simon Marlow | 1 Jun 2006 12:13
Picon

Re: [Haskell] My summer of code project: HsJudy

Bulat Ziganshin wrote:

> 1. In terms of Haskell, Judy is a library of _mutable_ collections of
> _unboxed_ elements. i pointed you to the Array wiki page, where
> differences between boxed and unboxed, mutable and immutable
> datastructures are described

There's no reason you can't use Judy to implement immutable collections, 
just as we use mutable arrays to implement immutable ones.

Cheers,
	Simon
Bulat Ziganshin | 1 Jun 2006 13:16
Picon

Re[2]: [Haskell] My summer of code project: HsJudy

Hello Simon,

Thursday, June 1, 2006, 2:13:03 PM, you wrote:

> Bulat Ziganshin wrote:

>> 1. In terms of Haskell, Judy is a library of _mutable_ collections of
>> _unboxed_ elements. i pointed you to the Array wiki page, where
>> differences between boxed and unboxed, mutable and immutable
>> datastructures are described

> There's no reason you can't use Judy to implement immutable collections,
> just as we use mutable arrays to implement immutable ones.

if you mean Data.Array.Base module (not Data.Array.Diff), then mutable
arrays used there only to _initialize_ immutable ones

--

-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin <at> gmail.com
Simon Marlow | 1 Jun 2006 14:47
Picon

Re: [Haskell] My summer of code project: HsJudy

Bulat Ziganshin wrote:

> Thursday, June 1, 2006, 2:13:03 PM, you wrote:

>>Bulat Ziganshin wrote:
>
>>>1. In terms of Haskell, Judy is a library of _mutable_ collections of
>>>_unboxed_ elements. i pointed you to the Array wiki page, where
>>>differences between boxed and unboxed, mutable and immutable
>>>datastructures are described
> 
>>There's no reason you can't use Judy to implement immutable collections,
>>just as we use mutable arrays to implement immutable ones.
>  
> if you mean Data.Array.Base module (not Data.Array.Diff), then mutable
> arrays used there only to _initialize_ immutable ones

Yes of course.  I'm objecting to your comment above, which implies that 
because Judy implements mutable collections, that is how they must be 
presented to the Haskell programmer.  That simply isn't the case, you 
can certainly use Judy as the substrate for an immutable collection type 
in Haskell.  Augmenting the collection might be inefficient, but that 
depends on how you implement it, just like arrays.  It would be 
appropriate in cases where you initialize a collection once, and then 
access it many times.

Cheers,
	Simon

Gmane