Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  hierarchy of modules (Stephen Tetley)
   2.  Ord [] instance (Keith Sheppard)
   3. Re:  Ord [] instance (Daniel Fischer)
   4. Re:  Ord [] instance (Keith Sheppard)
   5. Re:  Class definition syntax (Shawn Willden)
   6. Re:  Class definition syntax (Shawn Willden)
   7. Re:  Class definition syntax (Shawn Willden)
   8. Re:  Class definition syntax (Joe Fredette)
   9. Re:  Class definition syntax (Shawn Willden)


----------------------------------------------------------------------

Message: 1
Date: Sat, 31 Oct 2009 19:33:53 +0000
From: Stephen Tetley <stephen.tet...@gmail.com>
Subject: Re: [Haskell-beginners] hierarchy of modules
To: Michael Mossey <m...@alumni.caltech.edu>
Cc: beginners <beginners@haskell.org>
Message-ID:
        <5fdc56d70910311233w2cbfd9f6v9f80c8f7adc5a...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Hello Mike


An option I like is to put the main project files in a top level
directory called src, so your organization would look like this:

./src/Algo/Fux.hs
./src/Basics/CSound.hs
./src/Basics/Node.hs

I usually have a running example which has imports for all the files
in the project inside a top level folder called demo...

./demo/ImportAll.hs

For a GHCi session, I cd to $PROJECT/demo then

> ghci

Prelude> set -i../src

This is the useful bit of having all the project files under the src
hierarchy - the search path is very simple.

During development adding the files needed for cabal (Setup.hs,
project.cabal...) is still worthwhile - you can then generate
Haddock docs very easily. If you used Haddock in standalone mode you
would have to supply a few flags to tell which files to
document and where to put the output.

Each time you add or remove a module in the src tree, you should
re-run configure...

> runhaskell Setup.hs configure
> runhaskell Setup.hs haddock

but as your GHCi session is always using the interpreted project
source you don't need to run 'runhaskell Setup.hs build' and
'runhaskell Setup.hs install'.

Best wishes

Stephen


------------------------------

Message: 2
Date: Sat, 31 Oct 2009 15:39:57 -0400
From: Keith Sheppard <keiths...@gmail.com>
Subject: [Haskell-beginners] Ord [] instance
To: beginners@haskell.org
Message-ID:
        <92e42b740910311239pf614067w9eebcd51c7db2...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

the compare function for lists seems to be work like (leaving off
class details):

> compare [] [] = EQ
> compare [] _ = LT
> compare _ [] = GT
> compare (x:xt) (y:yt) = case x `compare` y of
>     EQ -> xt `compare` yt
>    _ -> x `compare` y

I poked around to see if I could find where this was defined in the
spec or if it was an implementation specific thing (I need to be able
to rely on this definition across implementations). I found this text
in the report:

-- Lists


data  [a]  =  [] | a : [a]  deriving (Eq, Ord)
-- Not legal Haskell; for illustration only

Is this basically saying the same thing as my compare definition?

Thanks
Keith

-- 
keithsheppard.name


------------------------------

Message: 3
Date: Sat, 31 Oct 2009 21:01:46 +0100
From: Daniel Fischer <daniel.is.fisc...@web.de>
Subject: Re: [Haskell-beginners] Ord [] instance
To: beginners@haskell.org
Message-ID: <200910312101.46296.daniel.is.fisc...@web.de>
Content-Type: text/plain;  charset="iso-8859-1"

Am Samstag 31 Oktober 2009 20:39:57 schrieb Keith Sheppard:
> the compare function for lists seems to be work like (leaving off
>
> class details):
> > compare [] [] = EQ
> > compare [] _ = LT
> > compare _ [] = GT
> > compare (x:xt) (y:yt) = case x `compare` y of
> >     EQ -> xt `compare` yt
> >    _ -> x `compare` y
>
> I poked around to see if I could find where this was defined in the
> spec or if it was an implementation specific thing (I need to be able
> to rely on this definition across implementations).

You can rely on lexicographic ordering for lists.

Haskell Report, section 10.1 ( 
http://haskell.org/onlinereport/derived.html#derived-
appendix ):

10.1  Derived instances of Eq and Ord
The class methods automatically introduced by derived instances of Eq and Ord 
are (==), 
(/=), compare, (<), (<=), (>), (>=), max, and min. The latter seven operators 
are defined 
so as to compare their arguments lexicographically with respect to the 
constructor set 
given, with earlier constructors in the datatype declaration counting as 
smaller than 
later ones.

> I found this text in the report:
>
> -- Lists
>
>
> data  [a]  =  [] | a : [a]  deriving (Eq, Ord)
> -- Not legal Haskell; for illustration only
>
> Is this basically saying the same thing as my compare definition?

Yes, see above.

>
> Thanks
> Keith



------------------------------

Message: 4
Date: Sat, 31 Oct 2009 16:16:55 -0400
From: Keith Sheppard <keiths...@gmail.com>
Subject: Re: [Haskell-beginners] Ord [] instance
To: Daniel Fischer <daniel.is.fisc...@web.de>, beginners@haskell.org
Message-ID:
        <92e42b740910311316y2061ed23q7f0630a0415e2...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Thank you

-Keith


------------------------------

Message: 5
Date: Sat, 31 Oct 2009 19:47:15 -0600
From: Shawn Willden <shawn-hask...@willden.org>
Subject: Re: [Haskell-beginners] Class definition syntax
To: beginners@haskell.org
Message-ID: <200910311947.16094.shawn-hask...@willden.org>
Content-Type: text/plain;  charset="iso-8859-1"

On Saturday 31 October 2009 10:33:10 am Joe Fredette wrote:
> You'll probably need to look at associated types/functional
> dependencies. The former is the new hotness, the latter is the old and
> not-so-busted. A quick search of the wiki ought to reveal much more
> than I can possibly explain, there is an example on the page for
> Assoc. Types about generic Map implementation, which is similar to
> what you're trying to do.

Hmm.  That looks like it will require a deeper dive into the theory than I 
want to make right now.  I don't yet understand what a kind is yet, much less 
how to write an appropriate kind signature.  It appears to be a somewhat 
disconcerting fact that learning Haskell requires reading original research 
papers on type theory and lambda calculus.  I suppose I need to get over my 
reluctance and dive into some of that -- but I lack the big slabs of time 
needed to immerse myself in it enough to make useful progress.

Learning Haskell appears to be something one should do as a college 
student :-)

        Shawn.


------------------------------

Message: 6
Date: Sat, 31 Oct 2009 19:55:02 -0600
From: Shawn Willden <shawn-hask...@willden.org>
Subject: Re: [Haskell-beginners] Class definition syntax
To: beginners@haskell.org
Message-ID: <200910311955.02397.shawn-hask...@willden.org>
Content-Type: text/plain;  charset="iso-8859-1"

On Saturday 31 October 2009 10:50:10 am Daniel Fischer wrote:
> Am Samstag 31 Oktober 2009 17:33:10 schrieb Joe Fredette:
> > You'll probably need to look at associated types/functional
> > dependencies. The former is the new hotness, the latter is the old and
> > not-so-busted. A quick search of the wiki ought to reveal much more
> > than I can possibly explain, there is an example on the page for
> > Assoc. Types about generic Map implementation, which is similar to
> > what you're trying to do.
>
> Or perhaps he should look at the class IArray from Data.Array.IArray, maybe
> he can just declare instances of IArray for his datatypes.
> Without more information, I can't tell which way to go.

This gives me some ideas, whether to use IArray directly, or just to use it as 
a model for my own class.

Thanks,

        Shawn.


------------------------------

Message: 7
Date: Sat, 31 Oct 2009 20:36:26 -0600
From: Shawn Willden <shawn-hask...@willden.org>
Subject: Re: [Haskell-beginners] Class definition syntax
To: beginners@haskell.org
Message-ID: <200910312036.26455.shawn-hask...@willden.org>
Content-Type: text/plain;  charset="iso-8859-1"

On Saturday 31 October 2009 10:50:10 am Daniel Fischer wrote:
> Or perhaps he should look at the class IArray from Data.Array.IArray, maybe
> he can just declare instances of IArray for his datatypes.
> Without more information, I can't tell which way to go.

Looking into the idea of declaring my types as IArray instances, there's one 
immediate problem:  IArray's only method is "bounds".  All of the functions 
that I want as methods of my class are functions in the IArray module (if I'm 
reading it correctly).

So, it seems like what I want to do is to subclass IArray and add the 
additional methods.  Then I can declare instances for my various types and 
define the methods appropriately.

So, I wrote this:

------------------------------------
import Data.Ix (Ix, inRange)
import qualified Data.Array.IArray (IArray, 
                                    Array,
                                    array,
                                    listArray,
                                    range,
                                    bounds,
                                    (!))

listArray   = Data.Array.IArray.listArray
array       = Data.Array.IArray.array              

class (Data.Array.IArray.IArray a e) => MyArray a e where
    bounds :: Ix i => a i e -> (i,i)
    range  :: Ix i => a i e -> [i]
    (!)    :: Ix i => a i e -> i -> e
    (//)   :: Ix i => a i e -> [(i,e)]

type Location = (Int, Int)
newtype Board = Board (Data.Array.IArray.Array Location Int)

instance MyArray Board where
    bounds = Data.Array.IArray.bounds
    (!)    = (Data.Array.IArray.!)
--------------------------------------

However, the instance declaration gives me a "kind mis-match" error.  It says 
that it expects kind '* -> * -> *', but Board has kind '*'.

So, I tried:

instance MyArray (Board Data.Array.IArray.Array Location Int) where

and other variations on that, but they all give me "Board is applied to too 
many type arguments".

How should this be written?

Thanks,

        Shawn.


------------------------------

Message: 8
Date: Sat, 31 Oct 2009 22:55:56 -0400
From: Joe Fredette <jfred...@gmail.com>
Subject: Re: [Haskell-beginners] Class definition syntax
To: Shawn Willden <shawn-hask...@willden.org>
Cc: beginners@haskell.org
Message-ID: <b3702b59-fdb2-4efc-ac57-a33859e54...@gmail.com>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes

Well, I think the issue is you're thinking too OOPy...

But let me answer the actual problem first, type classes are  
(basically) functions on types. So a type of "kind" `* -> * -> *`  
means it is a type which accepts two type variables. So:

        newtype Foo a b = Foo (a, b)

is a type of "kind" * -> * -> *, and if I wanted to implement the  
IArray class, I would write:

        instance IArray Foo where
                ...

because IArray is a type-function of type: "(* -> * -> *) - 
 > ..." (this is a little stretched, I think, but you get the idea.  
tl;dr is that "Board" doesn't have enough type arguments to be an  
IArray. However, I think this is part of a bigger problem.

By way of analogy, consider the Ord class, it implements things like  
`sort` as derived functions, not as parts of the class. Classes (at  
least in my estimation) are more like sets of axioms from math than  
like interfaces from OOP. So one doesn't so much "subclass" something  
as "add more assumptions" to it. So for instance, I can say, "assume a  
variable of type `a` which implements the Eq class", then if I want, I  
can say, "such a variable implements the Ord class if and only if it  
provides a `compare` or `<=` function". So, while I'm not sure of the  
specifics of your application and the abilities of IArray. Perhaps it  
is better to think about how to implement your functions in terms of  
the `bounds` function. In fact, this is what you do, but I think  
you're getting caught up in the type-classyness. Saying

        newtype Board = Board IArray ...

means that _you can just use the IArray types_! Well, almost, really  
what you want is a type-synonym:
        
        type Board = IArray Location ...

Now you can write functions like

        foo :: Board -> Int
        foo = Board !! (1,2)

and it will "just work" because Board _is_ an "IArray".

Hope that makes sense...



On Oct 31, 2009, at 10:36 PM, Shawn Willden wrote:

> On Saturday 31 October 2009 10:50:10 am Daniel Fischer wrote:
>> Or perhaps he should look at the class IArray from  
>> Data.Array.IArray, maybe
>> he can just declare instances of IArray for his datatypes.
>> Without more information, I can't tell which way to go.
>
> Looking into the idea of declaring my types as IArray instances,  
> there's one
> immediate problem:  IArray's only method is "bounds".  All of the  
> functions
> that I want as methods of my class are functions in the IArray  
> module (if I'm
> reading it correctly).
>
> So, it seems like what I want to do is to subclass IArray and add the
> additional methods.  Then I can declare instances for my various  
> types and
> define the methods appropriately.
>
> So, I wrote this:
>
> ------------------------------------
> import Data.Ix (Ix, inRange)
> import qualified Data.Array.IArray (IArray,
>                                    Array,
>                                    array,
>                                    listArray,
>                                    range,
>                                    bounds,
>                                    (!))
>
> listArray   = Data.Array.IArray.listArray
> array       = Data.Array.IArray.array
>
> class (Data.Array.IArray.IArray a e) => MyArray a e where
>    bounds :: Ix i => a i e -> (i,i)
>    range  :: Ix i => a i e -> [i]
>    (!)    :: Ix i => a i e -> i -> e
>    (//)   :: Ix i => a i e -> [(i,e)]
>
> type Location = (Int, Int)
> newtype Board = Board (Data.Array.IArray.Array Location Int)
>
> instance MyArray Board where
>    bounds = Data.Array.IArray.bounds
>    (!)    = (Data.Array.IArray.!)
> --------------------------------------
>
> However, the instance declaration gives me a "kind mis-match"  
> error.  It says
> that it expects kind '* -> * -> *', but Board has kind '*'.
>
> So, I tried:
>
> instance MyArray (Board Data.Array.IArray.Array Location Int) where
>
> and other variations on that, but they all give me "Board is applied  
> to too
> many type arguments".
>
> How should this be written?
>
> Thanks,
>
>       Shawn.
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://www.haskell.org/mailman/listinfo/beginners



------------------------------

Message: 9
Date: Sat, 31 Oct 2009 21:42:24 -0600
From: Shawn Willden <shawn-hask...@willden.org>
Subject: Re: [Haskell-beginners] Class definition syntax
To: Joe Fredette <jfred...@gmail.com>
Cc: beginners@haskell.org
Message-ID: <200910312142.24975.shawn-hask...@willden.org>
Content-Type: text/plain;  charset="iso-8859-1"

On Saturday 31 October 2009 08:55:56 pm Joe Fredette wrote:
> Well, I think the issue is you're thinking too OOPy...

I understand what you're saying, but I don't think I am.

> But let me answer the actual problem first, type classes are
> (basically) functions on types. So a type of "kind" `* -> * -> *`
> means it is a type which accepts two type variables. So:
>
>       newtype Foo a b = Foo (a, b)

Okay, that makes sense.  What I'd read about kinds was considerably less 
clear.  Thanks.

>       newtype Board = Board IArray ...
>
> means that _you can just use the IArray types_! Well, almost, really
> what you want is a type-synonym:
>
>       type Board = IArray Location ...
>
> Now you can write functions like
>
>       foo :: Board -> Int
>       foo = Board !! (1,2)
>
> and it will "just work" because Board _is_ an "IArray".
>
> Hope that makes sense...

It does make sense, but it doesn't solve my problem.  See, Board isn't the 
only type I have (and, also, Board has to be a newtype rather than a type 
synonym because it's also an instance of another class -- well, unless I want 
to turn on the extension that allows instances of synonyms, and I'm not sure 
what the etiquette is there), and some of the others aren't just IArrays with 
an aliased name, they have other data elements as well.  For example:

data ScoredBoard = ScoredBoard {
    arry     :: (IArray Location String)
    score    :: Int
    maxScore :: Int
}

I would like to be able to use (!), (//), bound, range, etc., on those as 
well, and without having to say "range (arry sb)", or having to define a 
bunch of fooRange, barRange, bazRange, etc., functions.

Basically I want to take this set of common array operations and overload them 
for a bunch of different types.  As I understand it, classes are effectively 
the only way to overload in Haskell.

Perhaps it just isn't possible to do what I want?  If kind signatures must 
match, then that's a problem, because different types will have different 
numbers of construction parameters.

Thanks for the help,

        Shawn.


------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 16, Issue 30
*****************************************

Reply via email to