Re: [Haskell-cafe] Re: [Haskell] Simple IO Regions

2006-01-19 Thread Keean Schupke

Andrew Pimlott wrote:


liftR :: (InRegion mark marks) = (h - m a) - Private mark h - Region marks 
m a
liftR f (Private h) = Region $ f h 
   



This is not as safe.  Try modifying your test2.
 

Okay, I missed this... Have renamed the function unsafeLiftR... As you 
say still useful for building
libraries provided you do not export the region code from the library 
that uses it.


Of course an alternative is just to have an opaque/abstract handle, and 
not export the data-constructor.


   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] Simple IO Regions

2006-01-18 Thread Keean Schupke

Taral wrote:


On 1/17/06, Keean Schupke [EMAIL PROTECTED] wrote:
 


   Just made a few modifications and thought it might be useful to
people. I have rewritten the functions as
liftR and bracketR over a MonadIO monad interface (allowing
monad-transformers to be used).
   



I'm sorry, but what is Lib.Monad.MonadT? How does up3 work? MonadIO
exists in Control.Monad.Trans.
 

It didnt when I wrote the MonadIO stuff that I use! Here is the missing 
file ... I tried to put it all in

one, but missed the use of up3. (see attached)

Regards,
   Keean.
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-} 

-- parser.hs: Copyright (C)2001,2002 Keean Schupke.
--
--		Polymorphic monadic consumer based parser.

module Lib.Monad.MonadT where

import Control.Monad hiding (guard)

--

class Runnable m n where
	run :: m - n 

instance Runnable (m a) (m a) where
	run = id

instance Runnable (s - m a) (s - m a) where
	run = id

class (Monad m,Monad (t m)) = MonadT t m where
	up :: m a - t m a
	up1 :: (m a - m a) - t m a - t m a
	up2 :: (m a - (b - m a) - m a) - t m a - (b - t m a) - t m a
	up3 :: (m a - (a - m b) - (a - m c) - m c) - t m a - (a - t m b) - (a - t m c) - t m c
	down :: t m a - m a
	up1 = undefined
	up2 = undefined
	up3 = undefined

-- instance (Monad m,Monad n,MonadT t m,Runnable (m a) (n a)) = Runnable (t m a) (n a) where
-- 	run = run . down

instance (Monad m,MonadT t m,Monad (t m)) = Runnable (t m a) (m a) where
	run = down 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] Simple IO Regions

2006-01-18 Thread Keean Schupke
up3 is quite easy to define, but it is specific to the monad-transformer 
you are lifting through... see attached for definition for

the state-monad-transformer.

   Keean.

Taral wrote:


On 1/18/06, Keean Schupke [EMAIL PROTECTED] wrote:
 


It didnt when I wrote the MonadIO stuff that I use! Here is the missing
file ... I tried to put it all in
one, but missed the use of up3. (see attached)
   



All I see is up3 = undefined... somehow I don't think that will work.

As far as I know, (t m a - m a) is only possible for very specific
monad transformers...

--
Taral [EMAIL PROTECTED]
Computer science is no more about computers than astronomy is about
telescopes.
   -- Edsger Dijkstra
 



{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-} 

-- parser.hs: Copyright (C)2001,2002 Keean Schupke.
--
--		Polymorphic monadic consumer based parser.

module Lib.Monad.StateT where

import Control.Monad hiding (guard)
import Lib.Monad.MonadT
import Lib.Monad.MonadState

--

newtype StateT st m a = ST { runST :: st - m (st,a) }

instance (MonadState st (StateT st m),Monad m) = Monad (StateT st m) where
	(ST m) = k = ST $ \s - do
		(s',a) - m s 
		(\(ST x) - x) (k a) s'
	return a = ST $ \s - return (s,a)

instance (MonadState st (StateT st m),MonadPlus m) = MonadPlus (StateT st m) where
	mzero = ST $ \_ - mzero
	(ST m) `mplus` (ST n) = ST $ \s - m s `mplus` n s

instance (MonadState st (StateT st m),Monad m) = MonadT (StateT st) m where
	up m = ST $ \s - do
		a - m
		return (s,a)
	up1 f m = ST $ \s - do
		a - f (downST m s)
		return (s,a)
	up2 f m n = ST $ \s - do
		a - f (downST m s) (downST' n s)
		return (s,a)
	up3 f m n o = ST $ \s - do
		a - f (downST m s) (downST' n s) (downST' o s)
		return (s,a)
	down (ST m) = do
		(_,a) - m undefined
		return a

downST :: Monad m = StateT st m a - (st - m a)
downST m = \st - do
	(_,a) - runST m st
	return a

downST' :: Monad m = (b - StateT st m a) - (st - b - m a)
downST' m = \st b - do
	(_,a) - runST (m b) st
	return a
	

instance (MonadState st (StateT st m),Monad m,Monad n,Runnable (st - m s) (st - n s)) = Runnable (StateT st m s) (st - n s) where
	run = run . downST 

instance (MonadState st (StateT st m),Monad m) = Runnable (StateT st m s) (st - m s) where
	run = downST

instance Monad m = MonadState st (StateT st m) where
	update st = ST $ \s - return (st s,s)
	setState st = ST $ \_ - return (st,())
	getState = ST $ \s - return (s,s)

instance (MonadState st m,MonadT t m) = MonadState st (t m) where
	update = up . update
	setState = up . setState
	getState = up $ getState
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell] Re: Haskell DB bindings (was Re: ANN: HDBC (Haskell Database Connectivity)

2006-01-17 Thread Keean Schupke

John  wrote:


On 2006-01-14, Keean Schupke [EMAIL PROTECTED] wrote:
 

Erm, has nobody replied to this yet? I want a robust interface, that 
uses bracket notation all the way down, so that any error is caught and 
resources are freed appropriately without the use of finalizers (which 
may not get run and lead to resource starvation - they are not reliable 
   



To be sure, your only failure situation in this case is if you're
dealing with many connections *and* creating/destroying them frequently.

Hopefully you wouldn't be.
 

You could be using connection pooling in the database driver or ODBC 
layer... Here the minimal
overhead of opening/closing allows you to use a bracket within each 
connection, rather than around
the whole server. Besides which the goal is not just to be safe in 
practice, but to be theoretically safe in all
circumstances. If you allow the programmer to shoot themselves in the 
foot, then they often will (for example
memory management and buffer overflows)... Its no good to partly remove 
responsibility, as that makes bugs
more likely not less likely (If the programmer has to deal with an 
opaque system with flaws, unless the programmer
is highly aware of those flaws they will take no account of them in 
their coding). The only way you can give the
programmer a genuine black box to play with, is if it is theoretically 
safe, then the programmer can (ab)use it

how they wish without accidentally breaking the conditions of usage.

Regards,
   Keean.

___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Simple IO Regions

2006-01-17 Thread Keean Schupke
I really like this Oleg... I think I will use this myself as much as 
possible in future... As my DB code already uses bracket notation and an 
opaque/abstract DB handle type, it should be quite easy to incorporate 
this, without changing the interface... Cool!


   Regards,
   Keean.

[EMAIL PROTECTED] wrote:


This message shows a very simple implementation of Monadic Regions
(for the particular case of IO and reading the file). The technique
*statically* guarantees that neither a file handle nor any computation
involving the handle can leak outside of the region that created
it. Therefore, the handle can be safely closed (and its resources
disposed of) whenever control leaves the corresponding 'withFile'
block. Many handles can be open simultaneously, the type system
enforces the proper nesting of their regions. The technique has no
run-time overhead and induces no run-time errors. Unlike the previous
implementation of monadic regions, only the basic extensions
(higher-ranked types and one two-parameter type class) are used. No
undecidable instances, no functional dependencies (let alone
overlapping instances) are required. In fact, the implementation uses
only one trivial typeclass and one trivial instance. 


Perhaps such an approach to File IO can be more widely used? It
trivially generalizes to database IO and other kinds of IO.

The motivation for monadic regions has been best explained by:

Brandon Moore wrote on Haskell Cafe:
 


I'm assuming you understand how the type on runST and the STRef
operations ensure that, even though you *can* smuggle out an STRef in
the result from runST, you will never be able to use it again.

The idea was to do the equivalent thing with databases: use fancy types
to ensure that handle can only be used inside to origination withDB or
withCursor or whatever, and the bracketing function can release the
resource on the way out, without worrying about it being used again.
   



Benjamin Franksen wrote:

 


I think this is an extremely good idea. I have been very frustrated
with finalizers because of their limitations (can't rely on them being
called at all), so have (reluctantly) been using the unsafe bracket
version. Making it safe via a type system trick is really the way to
go.
   




Let us start with the tests

 


{-# OPTIONS -fglasgow-exts #-}

module IORegionsTest where

import IORegions -- see below

test0 = withFile /etc/motd (const $ return True)

reader q = do
 c1 - qGetChar q
 c2 - qGetChar q
 return [c1,c2]

test1 = withFile /etc/motd reader
test1r = runIOM test1 = print
   



Instead of handles, we have Qs -- marked handles. The are created by
the function withFile and used similar to regular handles. A special
IOM monad is a newtype away from the regular IO. The phantom type
parameter of the IOM monad maintains the marks of the regions.

*IORegionsTest :t reader
reader :: (Monad (IOM marks), IORegions.IN mark marks) =
  Q mark - IOM marks [Char]

the type of the reader shows that it takes a marked handle and yields
a marked IO computation. The constraint IN assures that the
computation must be marked with the mark of the handle.

If we attempt to leak the handle:
* test2 = withFile /tmp/i.hs (\q - return q)

we get
   Inferred type is less polymorphic than expected
 Quantified type variable `mark' escapes
   In the second argument of `withFile', namely `(\ q - return q)'

The following is OK: we perform the computation and return its result:
 


test3 = withFile /etc/motd (\q -  (qGetChar q))
   



If we attempt to return the unperformed computation itself:
* test4 = withFile /tmp/i.hs (\q -  return (qGetChar q))

we get
   Could not deduce (IORegions.IN mark marks1)
 from the context (IORegions.IN mark marks)
 arising from use of `qGetChar' at IORegionsTest.h...

As we said earlier, more than one handle can be at play at the same
time:

 


reader2 q1 q2 = do
   c1 - qGetChar q1
   c2 - qGetChar q2
   return [c1,c2]
test5 = withFile /etc/motd (\q1 - 
			withFile /etc/motd (\q2 - reader2 q1 q2))


test5r = runIOM test5 = print
   



Incidentally, the inferred type of reader2 is

*IORegionsTest :t reader2
reader2 :: (Monad (IOM marks),
IORegions.IN mark1 marks,
IORegions.IN mark marks) =
   Q mark - Q mark1 - IOM marks [Char]

Obviously, the resulting computation is marked with the marks of both
argument handles.

With two handles, we can actually return a handle -- provided we
return an outermost handle from the innermost region (but not the
other way around). For example, the following is wrong

* test6 = withFile /etc/motd 
* 	(\q2 - 
* 	 do

*q' - withFile /etc/motd (\q - return q)
*qGetChar q')


but the following is OK:
 

test7 = withFile /etc/motd 
	   (\q2 - 
	do

q' - withFile /etc/motd (\q - return q2)

[Haskell-cafe] Re: [Haskell] Simple IO Regions

2006-01-17 Thread Keean Schupke

Hi Oleg,

   Just made a few modifications and thought it might be useful to 
people. I have rewritten the functions as
liftR and bracketR over a MonadIO monad interface (allowing 
monad-transformers to be used). This is now
usable as  Region library, as you can lift any arbitrary IO function 
into a Region. I don't think I have overlooked anything, and I
think it is as safe as the original... but perhaps you would like to 
check for stupid mistakes... The exported interface is intended

to be liftR, bracketR and runR. See attached MonadIORegion.hs...

   Regards,  
   Keean.


[EMAIL PROTECTED] wrote:


This message shows a very simple implementation of Monadic Regions
(for the particular case of IO and reading the file). The technique
*statically* guarantees that neither a file handle nor any computation
involving the handle can leak outside of the region that created
it. Therefore, the handle can be safely closed (and its resources
disposed of) whenever control leaves the corresponding 'withFile'
block. Many handles can be open simultaneously, the type system
enforces the proper nesting of their regions. The technique has no
run-time overhead and induces no run-time errors. Unlike the previous
implementation of monadic regions, only the basic extensions
(higher-ranked types and one two-parameter type class) are used. No
undecidable instances, no functional dependencies (let alone
overlapping instances) are required. In fact, the implementation uses
only one trivial typeclass and one trivial instance.
 

{-# OPTIONS -fglasgow-exts #-} 

-- parser.hs: Copyright (C)2001,2002 Keean Schupke.
--
--		Polymorphic monadic consumer based parser.

module Main where

import Control.Monad hiding (guard)
import Control.Concurrent
import Control.Exception as Exception
import Lib.Monad.MonadT 
import IO
import Network

--

class Monad m = MonadIO m where
	ioBracket :: m a - (a - m b) - (a - m c) - m c
	liftIO :: IO a - m a

instance MonadIO IO where
	ioBracket = Exception.bracket
	liftIO = id

instance (MonadIO m,MonadT t m) = MonadIO (t m) where
	ioBracket = up3 ioBracket
	liftIO = up . liftIO

--

newtype Region marks m a = Region { unRegion :: (m a) } deriving Monad
class InRegion a b
instance InRegion () b

newtype Private mark h = Private h
liftR :: (InRegion mark marks) = (h - m a) - Private mark h - Region marks m a
liftR f (Private h) = Region $ f h 

bracketR :: MonadIO m = m h - (h - m b) - (forall mark . InRegion mark marks = Private mark h - Region marks m a) - Region marks m a
bracketR f g h = Region $ ioBracket f g (\(x :: t) - unRegion $ h ((Private x) :: Private () t))

runR :: (forall mark . Region mark m a) - m a
runR = unRegion

test1 = bracketR (openFile /etc/services ReadMode) (hClose) (\f - do
	c1 - (liftR hGetChar) f
	c2 - (liftR hGetChar) f
	return [c1,c2])

-- test2 = bracketR (openFile /etc/services ReadMode) (hClose) (\f - return f)
test3 = bracketR (openFile /etc/services ReadMode) (hClose) (\f - (liftR hGetChar) f)
-- test4 = bracketR (openFile /etc/services ReadMode) (hClose) (\f - return ((liftR hGetChar) f))
-- test5 = bracketR (openFile /etc/services ReadMode) (hClose) (\f - f)

main = do
	runR test1 = print
	-- runR test2 = print
	runR test3 = print
	-- runR test4 = print

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell] Re: ANN: HDBC (Haskell Database Connectivity)

2006-01-13 Thread Keean Schupke

Yes, I see... I edited it from the source code, which actually has the type:

dbConnectWith :: VerifyTables t = (SqlHandle () - IO ()) - t - Query 
() - IO ()
dbConnectWith confn tabs query = confn (do { _ - runST (do verifyTables 
tabs ; query) 0; return () })


I obviously did not think hard enough about the changes I was making for 
readability...


Keean


Benjamin Franksen wrote:


On Monday 09 January 2006 10:03, Axel Simon wrote:
 


On Sun, 2006-01-08 at 14:51 +, Keean Schupke wrote:
   


My solution to this when developing a database library for my own
use was to define the API
in a bracket notation style, and only provide safe functions. The
idea is that the function obtains the resource, calls a function
passed as an argument, then frees the resource, so all resouces are
guaranteed to be freed in the correct order... for example:

dbConnectWith ::  DbName - (DbHandle - IO Result) - Result
dbConnectWith name workFn = do
   handle - dbConnectTo name
   workFn handle `finally` dbDisconnect handle

In this way you avoid finalizers... and everthing is safe providing
you only export the with style functions from the library...
Here's an example from the library, the connect function:
 


I suppose you meant to write result rather than Result. This
style of functions is only safe if the user ensures that DbHandle is
never returned as part of the result. You should have that in your
documentation.
   



I wanted to mention this too, but you were quicker ;)

 


As far as I can tell, the only general solution is to use finalizers
and, if you really need to enforce a sequence of finialization,
touchForeignPtr. 
   



Repeat: touchForeignPtr can NOT be used to enforce finalization order.

 

A practical issue with touchForeignPtr is that it 
cannot be conveniently called from another finalizer, since the
latter live in C. 
   



What do you mean live in C? Can't or shouldn't finalizers be written 
in Haskell, too?


Ben
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
 



___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Haskell DB bindings (was Re: ANN: HDBC (Haskell Database Connectivity)

2006-01-13 Thread Keean Schupke
Erm, has nobody replied to this yet? I want a robust interface, that 
uses bracket notation all the way down, so that any error is caught and 
resources are freed appropriately without the use of finalizers (which 
may not get run and lead to resource starvation - they are not reliable 
if dealing with many connections, unless you start forcing garbage 
collections). I want a simple interface (as few functions as possible to 
do the job) and robust exception handling.


I certainly like the idea of using runST to encapsulate the DbHandle... 
and infact the DB code I have does this, but not in a systematic way... 
I guess really all allocated handles that are passed to user defined 
functions need to be protected in this way.


The code I wrote is really to support a relational algebra layer over 
the top...


When I developed this there were no database drivers that worked under 
linux, as HSQL only supported ODBC under windows, so I developed an ODBC 
specific layer myself tested with unixODBC and iODBC.



So IMHO, braket notation, STRef encapsulation, no finalizers, lots of 
exception handling, minimal interface. I would sacrifice some speed for 
simplicity of interface...


   Keean

Krasimir Angelov wrote:


There are three active database libraries: HDBC, HSQL and Takusen. It
is quite disappointing from my point of view. Recently there was the
same situation with the GUI libraires. The Haskell Community is quite
small to waste efforts, developing different libraries for the same
things. When I started with HSQL there were only two database
libraries: HaSQL for ODBC and libpq for PostgreSQL. They both are
dead, I think. I decided that it is useful to have one abstract API
that can cover all database bindings. I imagine something like JDBC,
ADO or DBI for Haskell. If you guys would like this to happen then
lets discuss what we want. I would be happy to work on single project
that can satisfy all needs.

Cheers,
 Krasimir

2006/1/10, Tim Docker [EMAIL PROTECTED]:
 


[EMAIL PROTECTED] wrote:

   


Incidentally, the difficulty with finalizers was precisely the
argument for using enumerators rather than cursors in database
APIs. Takusen has implemented that idea; takusen currently supports
Sqlite, PostgreSQL and Oracle, has a test suite. Its performance test
shows that takusen can retrieve 2 million rows from a table without
running out of memory.
 


The differences between HDBC and HSQL have been recently discussed.
Where
does Takusen fit into this picture? From the above, it sounds like it
has
quite a different API. Are all 3 of these actively maintained?

As someone who may wish to construct a haskell db binding for a new db,
it's
not clear to which API it should conform. Sometimes choice is a
burden...

Tim

___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell

   


___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
 



___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Re: ANN: HDBC (Haskell Database Connectivity)

2006-01-08 Thread Keean Schupke
My solution to this when developing a database library for my own use 
was to define the API
in a bracket notation style, and only provide safe functions. The idea 
is that the function obtains the resource, calls a function passed as an 
argument, then frees the resource, so all resouces are guaranteed to be 
freed in the correct order... for example:


dbConnectWith ::  DbName - (DbHandle - IO Result) - Result
dbConnectWith name workFn = do
   handle - dbConnectTo name
   workFn handle `finally` dbDisconnect handle

In this way you avoid finalizers... and everthing is safe providing you 
only export the with style functions from the library... Here's an 
example from the library, the connect function:



safeConnect :: (SqlIO m,SqlIfIO m,MonadIO m,MonadPlus m) = SqlDbc - 
OdbcConnection - (SqlDbc - m a) - m a

safeConnect dbc connection doWith = ioBracket (
   ioBracket (ioNewCStringLen (odbcDsn connection)) 
(\(dsnS,_) - ioFree dsnS) (\(dsnS,dsnL) -
   ioBracket (ioNewCStringLen (odbcUid connection)) 
(\(uidS,_) - ioFree uidS) (\(uidS,uidL) -
   ioBracket (ioNewCStringLen (odbcAuth connection)) 
(\(authS,_) - ioFree authS) (\(authS,authL) - do
   status - ioSqlConnect dbc dsnS (fromIntegral 
dsnL) uidS (fromIntegral uidL) authS (fromIntegral authL)
   ioIfFail status (\s - fail ((showString  Bad 
status returned by sqlConnect ( . shows s) )))

   (\_ - ioSqlDisconnect dbc) (\_ - doWith dbc)


   Keean


Chris Kuklewicz wrote:


Benjamin Franksen wrote:
 


On Wednesday 04 January 2006 20:13, John Goerzen wrote:

   


Well, yes and no.  It would be impossible to garbage collect (and
thus finalize) any object for which references to it still exist. 
Statement handles in HDBC maintain references to the database handle

pointers, either directly or indirectly, so I can't see how it is
possible for a database handle to be finalized before the statement
handle in this situation.
 


Hi John,

I fear it /is/ possible. This is a very unfortunate situation and one I 
had quite some difficulties to understand, when Simon Marlow explained 
it to me.


The problem is that finalization of the statement handle might be 
delayed indefinitely. The data dependencies between statement and 
connection handle only ensures that whenever the statement handle is 
alive, then too is the connection handle. But it does not say anything 
about what happens in which order after /both/ are dead (garbage). As 
soon as the connection handle to garbage, too, bothe handles can be 
finalized in /any/ order.


As I pointed out before, this is a very bad thing, because it makes 
finalizers a whole lot less useful than they could be if an order 
between finalizations could be specified (directly or indirectly). The 
arguments against such a solution are mostly: (1) it is difficult to 
implement efficienty and (2) the programmer could accidentally cause 
finalizer deadlocks by specifying circular dependencies.


Ben
   



This is also mentioned in the documentation:

http://www.haskell.org/ghc/docs/6.4.1/html/libraries/base/Foreign-ForeignPtr.html#v%3AtouchForeignPtr

 


touchForeignPtr :: ForeignPtr a - IO ()

This function ensures that the foreign object in question is alive at the given 
place in the sequence of IO actions. In particular withForeignPtr does a 
touchForeignPtr after it executes the user action.

Note that this function should not be used to express liveness dependencies 
between ForeignPtrs. For example, if the finalizer for a ForeignPtr F1 calls 
touchForeignPtr on a second ForeignPtr F2, then the only guarantee is that the 
finalizer for F2 is never started before the finalizer for F1. They might be 
started together if for example both F1 and F2 are otherwise unreachable, and 
in that case the scheduler might end up running the finalizer for F2 first.

In general, it is not recommended to use finalizers on separate objects with ordering constraints between them. To express the ordering robustly requires explicit synchronisation using MVars between the finalizers, but even then the runtime sometimes runs multiple finalizers sequentially in a single thread (for performance reasons), so synchronisation between finalizers could result in artificial deadlock. 
   




___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
 



___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: GHCI and archive libraries.

2005-12-04 Thread Keean Schupke
Thaks guys... I realise it is a simple matter of unpacking the object 
files, however when using ghci for prototyping, it can be more 
convenient to have all the '.o's packed into a '.a'. As it is a simple 
matter to extract the .o files from the .a, I would have thought a 
fairly small change to the ghci code would have enabled using archive 
libraries. I think this change would aid usability. I don't know the 
ghci code at all, so it would take me a long time to make this change, 
as I would first have to understand the existing code. I was wondering 
if anyone familier with the ghci code could add archive library support? 
I suppose as a work around I could write a wrapper for ghci that 
extracts the .o files from the .a to a temp directory, and then calls 
ghci with the .o files on the command line.


   Regards,
   Keean.

Sven Panne wrote:


Am Samstag, 3. Dezember 2005 15:17 schrieb Lennart Augustsson:
 


And on many platforms (well, at least a few years ago) a shared
library doesn't have to be PIC.  The dynamic loader can do relocation
when it loads the file.  (Then it can't be shared.)

But this was a few years ago on Solaris and BSDs, it could be
different now.
   



After a quick look this seems to be the case on current x86 Linux systems, 
too: Real shared libraries consist of PIC to enhance sharing code at 
runtime, but nevertheless the dynamic loader seems to be able to load and 
relocate non-PIC, at the cost of less sharing, but often slightly better code 
quality. So the mentioned repacking of a static library into a partially 
linked object file might work for most common platforms.


Cheers,
  S.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
 



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


GHCI and archive libraries.

2005-12-03 Thread Keean Schupke


GHCI does not load archive libraries. Is it possible (easy?) to get it 
to load (.a) archive libraries as well as .o and .so files? The problem 
is some optimized cblas libraries are not available as shared 
libraries due to the performace loss.


   Regards,
   Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records (was Re: [Haskell] Improvements to GHC)

2005-11-24 Thread Keean Schupke

you can always do:


   case (field1 record,field2 record, field3 record ...) of
  (pat1,pat2,pat3) -
  _ -

Which lets you pattern match on fields independantly of their
position in the record.

   Keean.

David Roundy wrote:


On Wed, Nov 23, 2005 at 02:58:43PM +0100, Wolfgang Jeltsch wrote:
 


Am Mittwoch, 23. November 2005 14:22 schrieb David Roundy:
   


On Tue, Nov 22, 2005 at 02:32:47PM +, Rob Ennals wrote:
[...]
 


7. Unordered records: yep (if I understand the problem correctly)
   


...
 


You can just omit the data constructors from the module's export list.
   



Yes, you can do that if you don't want to allow pattern matching.  That's
an acceptable solution for truly exported (i.e. opaque) data, but for
internal data structures I would like to allow pattern matching without
allowing positional matching (or constructing).  Too many times I've had to
go through the entire code adding an extra _ to each pattern match, and
each time there's a possibility you'll add it in the wrong spot.  I could
do this with coding guidelines, but I'd prefer to have the compiler enforce
this.
 



___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell-cafe] Re: Records vs HList

2005-11-24 Thread Keean Schupke

David Menendez wrote:


Keean Schupke writes:

 


HList can do O(log n) by the way, if the labels have order, you can
implement a binary search tree of labels (Of course all the accessor
functions would need to be rewritten).
   



The idea of writing a type-level balanced binary search tree fills me
with an uncertain mixture of excitement and dread. Particularly if you
want to be able to compare records for equality.
 


Hmm... You have to write and define what you mean by equality
for normal HList records anyway. As you need to ignore the order
of elements the equality test is effectively:

a == b  if  (a `subset` b) and (b `subset` a)

The test for a subset b tests if each element in a exists in b.

With an ordered tree, the labels must be in the same order, so
the equality just has to compare elements is a consistant (say pre-order)
way.

In the end HList records were written as they are for clarity in the paper,
and not really as a number-crunching implementation. I find them fast
enough for database work, where the records represent the query (in terms
of projections) and the result table in a type safe way... Infact my 
simple DB

library goes quite a way beyond what HaskellDB can do, mainy due to the
complex type-mechanics being hidden inside the HList/record library.

   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Records vs HList

2005-11-23 Thread Keean Schupke

David Menendez wrote:


Keean Schupke writes:

 


David Menendez wrote:

   


Chris Kuklewicz writes:

 


Would the record system describe at
http://lambda-the-ultimate.org/node/view/1119
also be convertable into System Fw, GHC's existing, strongly-typeed
intermediate language. ?
   


Probably. Daan's current implementation uses MLF, which I believe is
system F implemented for ML.

(We're talking about the system in Daan Leijen's paper, Extensible
Records With Scoped Labels. Good stuff.)
 


You can change the project and update operators in the HList library
to behave in exactly this way. At the moment they are constrained to
not allow multiple identical labels in records. If this kind of
access is considered useful, I can add it to the HList distribution.
   



This is true. I've implemented a small subset of HList that's able to
emulate Daan's three record operators using only fundeps and undecidable
instances.

   *Main let r = foo .=. Bar .*. emptyRecord
   *Main r
   Record{foo=Bar}
   *Main let r2 = foo .=. () .*. r  
   *Main r2

   Record{foo=(),foo=Bar}
   *Main r2 .!. foo
   ()
   *Main (r2 .-. foo) .!. foo
   Bar

(This is actually *more* powerful than the system described in Daan's
paper, because labels are first class.)

While this is a testament to the power of Haskell's extended type-class
system, I'm not sure that it can replace a dedicated record system. In
his paper, Daan describes how to implement the records such that field
lookups take O(log n) or even O(1) time. HList can't do better than
O(n).

Of course, in the absence of a powerful record system, HList is the way
to go. Rather than decide on a new record system sight unseen, let's
implement them using HList and see how they feel.E
 

Exactly! I like the idea of being able to construct and modify the 
semantics of a record system
(and with the stuff in the OOHaskell paper you can play with Object 
systems in the same way).


The important point with HLists is not that record syntax should not be 
added to Haskell, but
that we can translate it to the existing type system with no conflicts. 
(ie the type system does not
need to be extended there just needs to be some syntax, with an 
optimised implementation)


HList can do O(log n) by the way, if the labels have order, you can 
implement a binary search
tree of labels (Of course all the accessor functions would need to be 
rewritten).


I wonder if some syntactic support for label creation would make things 
nicer.


Actually one really useful change I would like would be to define type 
class functions over all tuples,
that way you could write O(1) accessor functions on tuples using peano 
number indexes.


class TupleIdx u i t | u i - t where
   idx :: u - i - t
instance (a,b) HNil a where
   (a,_) _ = a
instance (a,b) (HSucc HNil) b where
   (_,b) _ = b
instance (a,b,c) HNil a where
   (a,_,_) = a
instance (a,b,c) (HSucc HNil) b where
   (_,b,_) = b
instance (a,b,c) (HSucc (HSucc HNil)) c where
   (_,_,c) = c

etc...

However I haven't thought very hard about how to represent the complete 
(infinite) set
of instances, but using this you can write products of tuples, and 
create records with O(1)

access times from a pair of tuples.

   Keean

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Existential quantification of environments.

2005-11-22 Thread Keean Schupke

If I have a function:

  f x y = add x y

and I want to type the function in isolation, then the type of 'add' is 
essentially carried in the environment... Lets say I want to make this 
type explicit in the type signature (where f is valid for any a where 
there is an add function on a - ignoring the class that Haskell would 
require for the overloading):


  add :: Int - Int - Int
  add :: Float - Float - Float

  f :: forall a . exists (add :: a - a - a) = a - a - a

or a step further:

  class Add a where
 add :: a - a - a
  instance Add Int where ...
  instance Add Float where ...

  f :: forall a . Add a = a - a - a

This seems to suggest:

   Add a == exists (add :: a - a - a)

Does this seem in any way right? It seems that the definition of 'f' 
does require the existance of 'add'. That is the definition is valid iff 
there exists a function called 'add' of the correct type. Also doesn't 
the existential quantifier stop you looking inside 'add' - obviously you 
cannot inspect the definition as it may not be defined (yet?), but 
presumably you can still apply 'add'.


   Regards,
   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] records proposals list

2005-11-22 Thread Keean Schupke
The HList code does not need overlapping-instances, however it does use 
undecidable
instances. This is not however bad like overlapping instances is. 
Overlapping instances
can break module independance (as in defining a new instance can change 
the meaning
of an existing class in modules that are already compiled). Undecidable 
instances merely
means the compiler is not capable of proving that the constraints 
terminate. In the
case of an HList they obviously do (where the constraint recursion is 
structurally over
the length of a list termination is obvious). This is more a weakness in 
the compiler rather

than some problem with the HList code.

   Keean.

Wolfgang Jeltsch wrote:


Am Dienstag, 22. November 2005 07:33 schrieb David Menendez:
 


Keean Schupke writes:
   


   Haskell already has static records (in H98)

   Dynamic records are addressed by the HList library, which uses
extensions already present in GHC and Hugs (namely Multi-parameter
type-classes and function-dependancies).
 


Is this the case? Every implementation of HList that I've seen also uses
overlapping and undecidable instances.
   



The paper about HList I have seen does explicitely say that the authors were 
finally able to avoid using overlapping instances.  I don't know about 
undecidable instances but I thought (and hope very much) that they don't need 
them too.


Best wishes,
Wolfgang
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] records proposals list

2005-11-22 Thread Keean Schupke

My mistake, what you want is:

   (   mything .=. something
   .*. value .=. (27::Int)
   .*. logic .=. True
   .*. HNil )

Admittedly the label creation would benefit from some syntactic sugar to
reduce typing...

Keean.

Bulat Ziganshin wrote:


Hello Keean,

Monday, November 21, 2005, 6:56:06 PM, you wrote:

KS So you can do this now... with reasonable syntax, for example to
KS create an extensible record

KS (some thing .*. (27 :: Int) .*. True .*. HNil)

KS is a statically typed anonymous record.
  
it is not record, but heterogenous list, in my feel. record must be

indexed by field name, not by type name or position


 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] records proposals list

2005-11-22 Thread Keean Schupke

Just a follow up to my last post ... The HList paper also presents a way of
removing overlapping instances from _any_ class. So infact support for 
overlapping
instances is no longer required - and this removes all the messy 
problems with

overlapping instances and functional dependancies.

The current HList source distribution runs in hugs with -98 +o only 
because of
lazyness on out part. All the occurances of overlapping instances can 
(will?) be

removed from the source if it becomes an important issue (most of them are
in auxilliary definitions that are not in the paper, like Show for HList.

If you program in the completely non overlapping instances model, then 
compiler

support for deriving TTypeable would be nice, or compiler support for a type
level equality constraint (TypeEq could become a built-in). But just to 
make it clear - compiler
support for this is not necessary, you just define instances of 
TTypeable for all your datatypes.
There is a template-haskell library that can automatically derive 
TTypeable for any datatype

as well.

   Keean.

David Menendez wrote:


Keean Schupke writes:

 


   Haskell already has static records (in H98)

   Dynamic records are addressed by the HList library, which uses 
extensions already present in GHC and Hugs (namely Multi-parameter 
type-classes and function-dependancies).
   



Is this the case? Every implementation of HList that I've seen also uses
overlapping and undecidable instances.
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Records

2005-11-22 Thread Keean Schupke
Just my 2p worth... If I were designing a language I would not have used 
the '.' like Haskell does. One problem is that ascii does not support 
enough symbols (Hmm, PL1 here we come). I guess my vote would go to 
keeping the '.' as is to not break existing programs, and using a 
different symbol for record access and qualified names... however '.' 
works well for DNS names:


   [EMAIL PROTECTED] -- function composition (people are used to reading the @ 
backwards due to emails)

   M.f -- qualified naming...
   f?f -- record access...

really needs more symbols... of course the problem then becomes entering 
them on a normal keyboard.


   Keean.

Ketil Malde wrote:


Cale Gibbard [EMAIL PROTECTED] writes:

 


This really isn't so bad in practice though. I've certainly never been
confused by it. 
   



Well, what can I say?  Good for you?

 


You'd have to go out of your way to construct a
situation in which it's potentially confusing
   



No.

 


There are much more important issues to deal with than this, really.
   



Like inventing as many new and wonderful symbolic operators as
possible!  Hey, why not allow quoted function names?  So that I can
defined a function f  different from f  ?  Or differentiate
(+4) from completely different  (+ 4), ( +4) and ( + 4) which
*obviously* are entirely differen things?

 


might be relevant in the IOHCC, but not in ordinary programming.
   



So why not go for the Obfuscated Language Design Contest instead?

 


In a sane language, small amounts of whitespace sensitivity are going
to be around no matter what you do.
   



And if you already are using whitespace to separate words, surely the
logical (not to mention aesthetical) way forward would be to introduce
evene more whitespace sensitivity - here is the Holy Grail
 http://compsoc.dur.ac.uk/whitespace/index.php 


I don't understand why this isn't obvious to people who generally
appear fairly bright, but: introducing extension that turns working
programs into non-working ones is generally a bad idea.  Having it be
due to spacing habits around symbolic operators is worse.  That
spacing changes suddenly starts bringing very complex language
extensions into the picture, with an associated heap of
incomprehensible error messages is *not* a nice thing for anybody -
except, perhaps, the two academics who wrote the paper, and the three
academics who read it.



/rant

Okay, I'm being unfair here.  Haskell is an academic language, its
primary purpose is to produce papers, not software.  And as a mere
programmer, I'm in a minority.  I think Haskell is really cool, but I
don't really belong here, and I realize of course that my voice isn't
going to carry a lot of weight.

But IF there is a desire for Haskell to be used for Real Work, I think
there should be a certain degree of stability.  Taking the function
composition operator and turning it into record selection -- depending
on spacing, of course -- is, IMO, madness.

But good luck on those papers, and see you later, probably on the
Clean mailing lists. 


-k
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Existential quantification of environments.

2005-11-22 Thread Keean Schupke
Excellent link thanks! Not quite what I was thinking of - but definitely 
related.
I'll give it a read and see if they want to existentially quantify 
environments...


   Keean.

Adrian Hey wrote:


On Tuesday 22 Nov 2005 10:39 am, Keean Schupke wrote:
 


If I have a function:

  f x y = add x y

and I want to type the function in isolation, then the type of 'add' is
essentially carried in the environment...
   



I am no expert in type theory so I'm probably about to get way
out of my depth, but isn't this what principal typings are all
about (as distinct from principal types). Maybe a look at type
system CT would be useful too.

http://www2.dcc.ufmg.br/~camarao/CT/

Regards
--
Adrian Hey
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pickling HList

2005-11-22 Thread Keean Schupke
This function is already in the HList library (well early versions 
anyway)... I dont think
this is in the current distribution. Its  a generic constructor  
wrapper. For example:


hMarkAll Just hlist

   class HList l = HMarkAll c l m | c l - m where
  hMarkAll :: (forall a . a - c a) - l - m
   instance HMarkAll c HNil HNil where
  hMarkAll _ _ = HNil
   instance HMarkAll c l m = HMarkAll c (HCons e l) (HCons (c e) m) where
  hMarkAll c (HCons e l) = HCons (c e) (hMarkAll c l)

   Keean.

Joel Reymont wrote:


Credit goes to Cale:

class (HList l, HList p) = HLPU p l | p - l, l - p where
puHList :: p - PU l

instance HLPU HNil HNil where
puHList HNil = lift HNil

instance (HList l, HLPU p l) = HLPU (HCons (PU e) p) (HCons e l) where
puHList (HCons pe l) =
wrap (\(a, b) - HCons a b,
  \(HCons a b) - (a, b))
  (pair pe (puHList l))


On Nov 10, 2005, at 2:04 PM, Joel Reymont wrote:


Folks,

I'm having trouble creating a pickler for HLists and would  
appreciate a solution.


The code for (HCons e HNil) works fine but I get an error trying to  
implement puHList for (HCons e l) where l is supposed to be (HCons  e 
...), i.e. another HList.


Bar.hs:21:37:
Couldn't match the rigid variable e' against PU e'
`e' is bound by the instance declaration at Bar.hs:17:0

Expected type: HCons (PU e) l Inferred type: HCons e l
In the first argument of puHList', namely l'

In the second argument of pair', namely (puHList l)'

Failed, modules loaded: none.



--
http://wagerlabs.com/





___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Existential quantification of environments.

2005-11-22 Thread Keean Schupke

Wolfgang Jeltsch wrote:


This seems to suggest:

   Add a == exists (add :: a - a - a)
   



Doesn't exists normally quantify over types and not over values?
 

It is quantifying over types, it is saying there exists a type a - a 
- a that has

at least one value we will call add...

I think the important point is that the existential is a pair of (proof, 
proposition)
which through curry-howard-isomorphism is (value in set, set). Here we 
are saying that
there is a set of functions with the type a - a - a ... for the 
existential to be satisfied
there must be one called add. Consider this as an assumption placed on 
the environment

by the function.

   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pickling HList

2005-11-22 Thread Keean Schupke
That all depends... In theory all the HList stuff happens at compile 
time, and what you are left with is normal function application... Of 
course compilers arn't that good yet, but as a reasonable idea, consider 
just that value level... Most of the extra work is the packing/unpacking 
of pairs (,). I have used HList for database schemas like the Cow 
example database (see attached) with no problems. The DB code includes 
code to generate the database from this Schema so is doesn't need to 
be entered twice, and it also typechecks the database against the schema 
in a one-way extensional manner on program start. The performance of the 
DB app is good, better than with scripting languages like perl/python, 
and type-safe.

This code uses records made from HLists (see the paper for examples).

   Keean.


Joel Reymont wrote:


Keean,

I sort of gave up on HList for the time being since I found easier  
ways to solve my problem.


Mainly, I could not estimate the impact it would have on run-time  
performance of my code and GHC not being able to compile the code was  
not a good indication. Simon PJ fixed that error since.


My idea was to, basically, create my own record sans labels. I wanted  
to specify picklers and default values for each field instead. I have  
over 250 records, though, and some have over 10 fields. There is a  
lot of sharing of fields between the records but I still think this  
is too much for GHC to handle.


Can you venture a guess on runtime performance of such code?

Thanks, Joel


On Nov 22, 2005, at 4:07 PM, Keean Schupke wrote:


hMarkAll Just hlist

   class HList l = HMarkAll c l m | c l - m where
  hMarkAll :: (forall a . a - c a) - l - m
   instance HMarkAll c HNil HNil where
  hMarkAll _ _ = HNil
   instance HMarkAll c l m = HMarkAll c (HCons e l) (HCons (c e)  m) 
where

  hMarkAll c (HCons e l) = HCons (c e) (hMarkAll c l)



--
http://wagerlabs.com/







{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-overlapping-instances #-}
{-# OPTIONS -fallow-undecidable-instances #-}

module Lib.Relational.FamDb where

import Char
import Lib.ODBC.Types
import Lib.TIR.HList
import Lib.TIR.HTypeGHC
import Lib.TIR.HRecord
import Lib.Relational.Types as SQL

---
-- Foot and Mouth Database

famdb :: (FarmerTable:*:FarmTable:*:AnimalTable:*:ContaminatedTable:*: HNil)
famdb = (farmerTable.*.farmTable.*.animalTable.*.contaminatedTable.*.HNil)

---
-- Domains

newtype DFarmerId = DFarmerId Int deriving (Show,Eq,ToSqlType SqlInteger,FromSqlType SqlInteger)
newtype DFarmerName = DFarmerName String deriving (Show,Eq,ToSqlType SqlVarchar,FromSqlType SqlVarchar)
newtype DFarmId = DFarmId Int deriving (Show,Eq,ToSqlType SqlInteger,FromSqlType SqlInteger)
newtype DFarmName = DFarmName String deriving (Show,Eq,ToSqlType SqlVarchar,FromSqlType SqlVarchar)
newtype DFarmCounty = DFarmCounty String deriving (Show,Eq,ToSqlType SqlVarchar,FromSqlType SqlVarchar)
newtype DAnimalId = DAnimalId Int deriving (Show,Eq,ToSqlType SqlInteger,FromSqlType SqlInteger)
newtype DAnimalName = DAnimalName String deriving (Show,Eq,ToSqlType SqlVarchar,FromSqlType SqlVarchar)
data DAnimalType = Cow | Sheep deriving (Show,Eq)
newtype DAnimalPrice = DAnimalPrice Float deriving (Show,Eq,ToSqlType SqlNumeric,FromSqlType SqlNumeric)
data DCntdType = BSE | FM deriving (Show,Eq)

instance FromSqlType SqlVarchar DAnimalType where
   fromSqlType _ s = case (map toLower s) of
  cow - Just Cow
  sheep - Just Sheep
  _ - Nothing
 
instance ToSqlType SqlVarchar DAnimalType where
   toSqlType Cow = SqlTyped (SqlExpressionConst $ sqlShow cow )
   toSqlType Sheep = SqlTyped (SqlExpressionConst $ sqlShow sheep )

instance FromSqlType SqlVarchar DCntdType where
	fromSqlType _ s = case (map toLower s) of
		bse - Just BSE
		fm - Just FM
		_ - Nothing

instance ToSqlType SqlVarchar DCntdType where
	toSqlType BSE = SqlTyped (SqlExpressionConst $ sqlShow BSE )
	toSqlType FM = SqlTyped (SqlExpressionConst $ sqlShow FM )

---
-- Farmer table

data FarmerId = FarmerId deriving Show
data FarmerName = FarmerName deriving Show

type FarmerTable = Table (
	FarmerId :=: Attribute DFarmerId SqlInteger :*:
	FarmerName :=: Attribute DFarmerName SqlVarchar :*:
	HNil)	

farmerTable :: FarmerTable
farmerTable =  newTable Farmer (
	FarmerId .=. Attribute (attr { attrName=farmerid, attrType=SERIAL }) .*.
	FarmerName .=. Attribute (attr { attrName=name, attrSize=20 }) .*.
	HNil)

---
-- Farm table

data FarmId = FarmId deriving Show
data FarmName = FarmName deriving Show
data FarmCounty = FarmCounty deriving

Re: [Haskell-cafe] records proposals list

2005-11-21 Thread Keean Schupke

Hi,

   Haskell already has static records (in H98)

   Dynamic records are addressed by the HList library, which uses 
extensions already present in GHC and Hugs (namely Multi-parameter 
type-classes and function-dependancies).


   So you can do this now... with reasonable syntax, for example to 
create an extensible record


   (some thing .*. (27 :: Int) .*. True .*. HNil)

   is a statically typed anonymous record.
  

   In other words there is no need for any more extensions to GHC or 
Hugs to implement Records (although  having a type-level type-equality 
constaint would simplify the internal implementation of the library)...


   For details see the HList paper: http://homepages.cwi.nl/~ralf/HList/

   Regards,  
   Keean.


Bulat Ziganshin wrote:


Hello Haskell,

 can anyone write at least the list of record proposals for Haskell?
or, even better, comment about pros and contras for each proposal?

 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Spurious program crashes

2005-11-21 Thread Keean Schupke
One thing, which I am sure you must have got right, but which burned me, 
is that you must explicitly free enitities created by FFI calls.


For example network sockets exist outside of the haskell runtime, and 
are not free'd automatically when a haskell thread is killed, you need 
an explicit exception handler to close the handle... They may eventually 
be garbage collected - but your application may run out of resources 
before this happens.


   Keean.

Joel Reymont wrote:

Maybe one of the Simons can comment on this. I distinctly remember  
trying the mdo approach to kill the other thread and getting burned  
by that. Don't know why I forgot to mention it.


On Nov 17, 2005, at 2:03 PM, Sebastian Sylvan wrote:


What I do remember is that the timeout and parIO functions in the
concurrent programming papers I found were NOT correct. killThread did
NOT behave as expected when I killed an already killed thread.
I tried multiple tricks here (including some which required recursive
do-notation) to try to get the parIO function to only kill the *other*
thread.
This could be done by having the two spawned threads take their
computations in an MVar along with the threadID of the other thread.



--
http://wagerlabs.com/





___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Records (was Re: [Haskell] Improvements to GHC)

2005-11-21 Thread Keean Schupke
You can change the project and update operators in the HList library to 
behave
in exactly this way. At the moment they are constrained to not allow 
multiple
identical labels in records. If this kind of access is considered 
useful, I can

add it to the HList distribution.

   Keean.

David Menendez wrote:


Chris Kuklewicz writes:

 


Would the record system describe at
http://lambda-the-ultimate.org/node/view/1119
also be convertable into System Fw, GHC's existing, strongly-typeed
intermediate language. ?
   



Probably. Daan's current implementation uses MLF, which I believe is
system F implemented for ML.

(We're talking about the system in Daan Leijen's paper, Extensible
Records With Scoped Labels. Good stuff.)
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Records (was Re: [Haskell] Improvements to GHC)

2005-11-21 Thread Keean Schupke
Can this not be done with the HList code? I am pretty sure you should be 
able to
map projections over HLists of HLists... (although the HList generic map 
is a bit

ugly, requiring instances of the Apply class).

Actually you should look in the OOHaskell paper (if you haven't already) 
where it

discusses using narrow to allow homogeneous lists to be projected from
heterogeneous ones...

   Keean.

John Meacham wrote:


another thing is that for any record syntax, we would want higher order
versions of the selection, setting, and updating routines. A quick
perusal of my source code shows over half my uses of record selectors
are in a higher order fashion. (which need to be generated with DrIFT
with the current syntax)

I mean something like 


map (.foo) xs
to pull all the 'foo' fields out of xs.  (using made up syntax)

or 


map (foo_s 3) xs

to set all the foo fields to 3. (using DrIFT syntax)


   John

 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Interactive Haskell and hs-plugins

2005-11-01 Thread Keean Schupke
The symbols must be exported from the main program... I think you can 
pass the linker an option to force it to export symbols.


   Keean.

Fraser Wilson wrote:


Hi there,

I would like to use evaluate arbitrary expressions in the context of a 
mixed-language (Ada, Haskell and about twelve lines of C glue) 
applications.  Is it possible to use dynload from hs-plugins to load a 
module that references symbols in the loading program?


For example, the application contains a Haskell module that looks a 
bit like this:


 module TestKeys.NamedObject where
tt :: Int
tt = 2

I want the application to be able to offer the following sort of 
interaction:


haskell tt
2
haskell

But what actually happens is this:

haskell tt
test_haskell3: /tmp/MDnum15633.o: unknown symbol 
`TestKeysziNamedObject_tt_closure'

test_haskell3: user error (resolveObjs failed with False)

Compiling Haskell code in advance works (i.e. if I create and compile 
a module that evalutes tt and link it in, everything runs fine).


This is how I try to evaluate the expression:

 evaluate :: String - IO ()
 evaluate  = return ()
 evaluate e = do writeFile temp.hs fileContents
 status - makeWith LeanderStub.hs temp.hs [-c]
 case status of MakeSuccess code path - loadAndEval path
MakeFailure error - print error
 where fileContents = module Temp where\n\
  \   result =  ++ e ++ \n

 loadAndEval :: FilePath - IO ()
 loadAndEval path = do mv - dynload path [] [] result
   case mv of
LoadFailure msg - print msg
LoadSuccess _ v - putStrLn v

LeanderStub.hs is a module containing the necessary imports for the 
expression to evaluate in the right context.


I was hoping that passing -c to makeWith would create an object file 
whose missing dependencies would be resolved when it was loaded into 
an application which contained them.  Is this a dumb expectation?  The 
alternative -- linking to the entire application for each expression 
evaluated -- seems a bit over the top, and I can't see how state would 
be maintained.


I originally used unsafeEval_, but this has the same problem.

I can't help but think that this must have been done before.  Any 
advice?  If you know Guile, then the equivalent of gh_repl is what I'm 
really after.


cheers,
Fraser.



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-23 Thread Keean Schupke

Andrew Pimlott wrote:


On Tue, Sep 20, 2005 at 03:01:32PM +0100, Keean Schupke wrote:
 


  (see attachment for files)
   



You didn't include all the used libraries (MonadControl, MonadState).

Andrew
 

Oops, here they are (it was extracted from a larger project), sorry 
about that...
(Have posted this back to the mailing list incase anyone else is tying 
to use the

libraries I posted)

   Regards,
   keean.



parser.tgz
Description: application/compressed-tar
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke

John Goerzen wrote:


On 2005-09-15, Adam Turoff [EMAIL PROTECTED] wrote:
 


On 9/15/05, John Goerzen [EMAIL PROTECTED] wrote:
   


So, to make that approach work, I would really need to do a lot of work
outside of Parsec -- the stuff that I really want to use Parsec for, I
think.
 


Well, you do have a state monad to work with.  Why not just stuff
the number 305 into your state, keep reading until you've read 305 bytes 
(decrementing the count as you read), and return the 305-byte string 
as your result for this parser?  When you resume,  you should 
be ready to parse the next very token after the 305-byte string.
   



It's unclear to me exactly how to mix the IO monad with Parsec.  It
doesn't really seem to be doable.

Not to mention that if hGetContents is used, the Handle has to be put
into non-buffering mode, which means one syscall per character read.
Terribly slow.

 


Does it? I didn't think so ...

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke
You may like my parser transformer then (based on the efficent 
backtracking parser paper, I believe by Ralf Heinze - uses endofunctor 
and continuation passing - Its a long time since I tested it but I think 
it holds its own against Parsec, without requiring the extra return types).


-- parser.hs: Copyright (C)2001,2002 Keean Schupke.
--
--  Polymorphic monadic consumer based parser.

module Lib.Monad.ParserT(ParserT(..)) where

import Control.Monad hiding (guard)
import Control.Monad.Error
import Lib.Monad.MonadT
import Lib.Monad.MonadState
import Lib.Monad.MonadParser
import Lib.Monad.MonadControl
import Lib.Arrow.Runnable

--
-- An continuation passing endomorphic parser

type Cps a r = (a - r) - r
type Endo r = r - r

newtype ParserT r tok m a = PT (Cps a ([tok] - Endo (m r)))

instance Monad m = Functor (ParserT r tok m) where
   fmap g (PT m) = PT $ \k - m (\a s f - k (g a) s f)

instance Monad m = Monad (ParserT r tok m) where
   {-# INLINE return #-}
   return a = PT $ \k - k a
   {-# INLINE (=) #-}
   (PT m) = f = PT $ \k - m (\a - (\(PT x) - x) (f a) k)

instance Monad m = MonadPlus (ParserT r tok m) where
   {-# INLINE mzero #-}
   mzero = PT $ \_ _ f - f
   {-# INLINE mplus #-}
   mplus (PT m) (PT n) = PT $ \k s - m k s . n k s

instance MonadPlus m = MonadT (ParserT r tok) m where
   {-# INLINE up #-}
   up m = PT $ \k s f - (m = \a - k a s mzero) `mplus` f
   {-# INLINE down #-}
   down = undefined

instance (MonadPlus m,MonadT (ParserT r tok) m,Runnable ([tok] - m 
([tok],r)) ([tok] - n ([tok],r)))
   = Runnable (ParserT ([tok],r) tok m r) ([tok] - n 
([tok],r)) where
   run = run . (\(PT m) t - m (\a t' f - return (t',a) `mplus` f) 
t mzero)


instance (MonadPlus m,MonadT (ParserT r tok) m)
   = Runnable (ParserT ([tok],r) tok m r) ([tok] - m 
([tok],r)) where

   run = (\(PT m) t - m (\a t' f - return (t',a) `mplus` f) t mzero)

instance Monad m = MonadState [tok] (ParserT r tok m) where
   {-# INLINE update #-}
   update st = PT $ \k s - k s ((st s) `asTypeOf` s)
   setState st = PT $ \k _ - k () st
   getState = PT $ \k s - k s s


instance Monad m = MonadParser tok (ParserT r tok m) where
   {-# INLINE item #-}
   item = PT $ \k s - case s of
   [] - id
   (a:x) - k a x

instance (MonadPlus (t m),MonadParser tok m,MonadT t m) = MonadParser 
tok (t m) where

   item = up item

instance Monad m = MonadControl (ParserT r tok m) where
   {-# INLINE once #-}
   once (PT m) = PT $ \k s f - m (\a s' _ - k a s' f) s f

Regards,
   Keean.

John Goerzen wrote:


On 2005-09-16, Andrew Pimlott [EMAIL PROTECTED] wrote:
 


On Thu, Sep 15, 2005 at 06:11:58PM -0700, Andrew Pimlott wrote:
   


I don't see why this would be more error-prone than any other approach.
 


Hmm... I take that back.  I don't know anything about the IMAP protocol,
but after imagining for a few moments what it might be like, I can see
how it could be more difficult than my example.

The user state of the parser might help you...
   



Hmm, can you elaborate on that?

Basically, I *really* want to get away frmo having to use hGetContents.
It is just not at all friendly for an interactive netwrk protocol.  If I
were just streaming a large file from an FTP server, it would be fine,
but even using it to begin with involves using Handles in a nonstandard
way (since there must be a separate Handle for writing, since
hGetContents sents the Handle to be half-closed) that is apparently not
well-supported.

-- John

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke

Here's some useful definitions to go with that...

module Lib.Parser.Parser(Parser,when,unless,guard,(|),opt,many,many1,sepBy,
   
parse,alpha,digit,lower,upper,other,lexical,satisfy,optional,literal,untilP,untilParser,matchP) 
where ...


   (see attachment for files)

   Regards,
   Keean.



parser.tgz
Description: application/compressed-tar
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke

John Goerzen wrote:


On Tue, Sep 20, 2005 at 02:29:12PM +0100, Keean Schupke wrote:
 


It's unclear to me exactly how to mix the IO monad with Parsec.  It
doesn't really seem to be doable.

Not to mention that if hGetContents is used, the Handle has to be put
into non-buffering mode, which means one syscall per character read.
Terribly slow.



 


Does it? I didn't think so ...
   



strace seems to say yes.
 

Thats odd, the source code  seems to suggest that when you read past the 
end of the buffer
it reads the next entire buffer (it has cases for each possible buffer 
configuration, line, block and none) - and I can think of no reason 
_why_ it cannot use buffering... I would think that it's a bug if it is 
the case.


   Regards,
   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke

Here's the code from hGetContents (base/GHC/IO.lhs):

   -- we never want to block during the read, so we call fillReadBuffer 
with

   -- is_line==True, which tells it to just read what there is.
   lazyReadBuffered h handle_ fd ref buf = do
  catch
   (do buf - fillReadBuffer fd True{-is_line-} (haIsStream 
handle_) buf

   lazyReadHaveBuffer h handle_ fd ref buf
   )
   -- all I/O errors are discarded.  Additionally, we close the 
handle.

   (\e - do handle_ - hClose_help handle_
 return (handle_, )
   )

So, it reads whatever is available, further description is available 
from the definition

of fillReadBuffered:

   -- For a line buffer, we just get the first chunk of data to arrive,
   -- and don't wait for the whole buffer to be full (but we *do* wait
   -- until some data arrives).  This isn't really line buffering, but it
   -- appears to be what GHC has done for a long time, and I suspect it
   -- is more useful than line buffering in most cases.

So for a disc buffer I would expect 1 complete buffer to be returned 
most of the time, for

a network read, I guess one packet (MTUs) worth should be expected...


   Regards,
   Keean.





Keean Schupke wrote:


John Goerzen wrote:


On Tue, Sep 20, 2005 at 02:29:12PM +0100, Keean Schupke wrote:
 


It's unclear to me exactly how to mix the IO monad with Parsec.  It
doesn't really seem to be doable.

Not to mention that if hGetContents is used, the Handle has to be put
into non-buffering mode, which means one syscall per character read.
Terribly slow.






Does it? I didn't think so ...
  



strace seems to say yes.
 

Thats odd, the source code  seems to suggest that when you read past 
the end of the buffer
it reads the next entire buffer (it has cases for each possible buffer 
configuration, line, block and none) - and I can think of no reason 
_why_ it cannot use buffering... I would think that it's a bug if it 
is the case.


   Regards,
   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Network parsing and parsec

2005-09-20 Thread Keean Schupke

John Goerzen wrote:


On Tue, Sep 20, 2005 at 03:05:25PM +0100, Keean Schupke wrote:
 


strace seems to say yes.


 

Thats odd, the source code  seems to suggest that when you read past the 
end of the buffer
it reads the next entire buffer (it has cases for each possible buffer 
configuration, line, block and none) - and I can think of no reason 
_why_ it cannot use buffering... I would think that it's a bug if it is 
the case.
   



Because the next entire buffer might consume more data than the remote
has sent.  That results in deadlock.
 


Would it not be usual to have a timeout incase of dropped connection?

   Regards,
   Keean.

(Btw, did you look at the Parser Monad-Transformer?)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell] Mixing monadic and non-monadic functions

2005-09-09 Thread Keean Schupke

Malcolm Wallace wrote:


Wolfgang Jeltsch [EMAIL PROTECTED] writes:

 


I'm not sure exactly what you have in mind. Obviously I want something
that applies to all functions, with any number of arguments, and not
just (+). Furthermore, it should handle cases like 1+[2,3] where only
one value is monadic.
 


I doubt that it is a good thing to extend the language in a way that such
far  reaching declarations are automatically generated.
   



I agree.  The original request was for something like
   [1,2] + [3,4]
to be automatically lifted into a monad.  But surely it is not too
difficult to define the required behaviour precisely (and only)
where needed, e.g.

   (+.) = liftM2 (+)

   [1,2] +. [3,4]

 

Why not make the monad an instance of Num, then you do not proliferate 
meaningless
similar symbols... besides which I am sure all the good ones are used in 
libraries already

(like +. + etc) ;)

instance (Monad m, Show a) = Show (m a)
  ...
instance (Monad m, Ord a) = Ord (m a)
  ...
instance (Monad m, Num a,Show (m a),Ord (m a)) - Num (m a) where
   (+) = liftM2 (+)

The instances for Show and Ord can be empty if you don't need the 
functionality...


   Regards,
   Keean.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Mixing monadic and non-monadic functions

2005-09-09 Thread Keean Schupke

Keean Schupke wrote:


I'm not sure exactly what you have in mind. Obviously I want something
that applies to all functions, with any number of arguments, and not
just (+). Furthermore, it should handle cases like 1+[2,3] where only
one value is monadic.


Just noticed the 1+[1,2] case...  I am not certain whether this is 
possible - it is outside the
scope of the formal definiton of Haskell and may rely on implementation 
details of the compiler/interpreter.


Effectivly we need to redefine list as a class, then (Num a) can be made 
an instance of the class... See my implementation of Joy in the HList 
library. (this lifts numbers into an AST rather than a list) - this 
however uses type level programming and has problems with non static 
types (IE you need to use existentials for lists who's values is not 
known at compile time)...


The easy answer is to define a type that contains both singletons and 
lists... although the type constructors may not look as neat.


   Regards,
   Keean.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Mixing monadic and non-monadic functions

2005-09-08 Thread Keean Schupke

Can't you do automatic lifting with a Runnable class:

   class Runnable x y where
  run :: x - y

   instance Runnable (m a) (m a) where
   run = id

   instance Runnable (s - m a) (s - m a) where
   run = id
 
   instance (Monad m,Monad n,MonadT t m,Runnable (m a) (n a)) = 
Runnable (t m a) (n a) where

   run = run . down

   instance (Monad m,MonadT t m,Monad (t m)) = Runnable (t m a) (m a) 
where

   run = down

Where:

   class (Monad m,Monad (t m)) = MonadT t m where
  up :: m a - t m a
  down :: t m a - m a

For example for StateT:

   downST :: Monad m = StateT st m a - (st - m a)
   downST m = \st - do
   (_,a) - runST m st
   return a

   downST' :: Monad m = (b - StateT st m a) - (st - b - m a)
   downST' m = \st b - do
   (_,a) - runST (m b) st
   return a


   instance (MonadState st (StateT st m),Monad m,Monad n,Runnable (st 
- m s) (st - n s)) = Runnable (StateT st m s) (st - n s) 
where

   run = run . downST

   instance (MonadState st (StateT st m),Monad m) = Runnable (StateT 
st m s) (st - m s) where

   run = downST

Keean.

 


Frederik Eaton wrote:


Hi,

Sean's comment (yeah, it was like a billion years ago, just catching
up) is something that I've often thought myself. 


I want the type system to be able to do automatic lifting of monads,
i.e., since [] is a monad, I should be able to write the following:

[1,2]+[3,4]

and have it interpreted as do {a-[1,2]; b-[3,4]; return (a+b)}.

Also, I would have

Reader (+1) + Reader (+4) == Reader (\x - 2*x+5)

The point I want to make is that this is much more general than IO or
monads! I think we all understand intuitively what mathematicians mean
when they add two sets

{1,2}+{3,4}  (i.e. { x+y | x\in {1,2}, y\in {3,4}})

or when they add functions 


(f+g)(x) where f(x)=x+1 and g(x)=x+4

So automatic lifting is a feature which is very simple to describe,
but which gives both of these notations their intuitive mathematical
meaning - not to mention making monadic code much tidier (who wants to
spend their time naming variables which are only used once?). I think
it deserves more attention.

I agree that in its simplest incarnation, there is some ugliness: the
order in which the values in the arguments are extracted from their
monads could be said to be arbitrary. Personally, I do not think that
this in itself is a reason to reject the concept. Because of currying,
the order of function arguments is already important in Haskell. If
you think of the proposed operation not as lifting, but as inserting
`ap`s:

return f `ap` x1 `ap` ... `ap` xn

then the ordering problem doesn't seem like such a big deal. I mean,
what other order does one expect, than one in which the arguments are
read in the same order that 'f' is applied to them?

Although it is true that in most of the instances where this feature
would be used, the order in which arguments are read from their monads
will not matter; yet that does not change the fact that in cases where
order *does* matter it's pretty damn easy to figure out what it will
be. For instance, in

print (a:  ++ readLn ++ \nb:  ++ readLn)

two lines are read and then printed. Does anybody for a moment
question what order the lines should be read in?

Frederik



On Tue, Mar 23, 2004 at 12:55:56PM -0500, Sean E. Russell wrote:
 


On Tuesday 23 March 2004 11:36, Graham Klyne wrote:
   


I think you're a rather stuck with the temporary variables (which they're
not really), but it might be possible to hide some of the untidiness in an
auxiliary monadic function.
 


That seems to be the common suggestion: write my own visitors.

I'm just surprised that there isn't a more elegant mechanism for getting 
interoperability between monadic and non-monadic functions.  The current 
state of affairs just seems awkward.  


[Warning: quasi-rant]

Caveat: I'm not smart enough, and I don't know enough, to criticize Haskell, 
so please don't misconstrue my comments.  To quote Einstein: When I'm asking 
simple questions and I'm getting simple answers, I'm talking to God.  I 
simply mistrust, and therefore question, systems where simple things are 
overly involved.


The standard explaination about why monads are so troublesome always sounds 
like an excuse to me.  We have monads, because they allow side-effects.  Ok.  
If programs that used side effects were uncommon, I'd be fine with them being 
troublesome -- but they aren't.  Maybe it is just me, but my Haskell programs 
invariably develop a need for side effects within a few tens of lines of 
code, whether IO, Maybe, or whatnot.  And I can't help but think that 
language support to make dealing with monads easier -- that is, to integrate 
monads with the rest of the language, so as to alleviate the need for 
constant lifting -- would be a Good Thing.


Hmmm.  Could I say that Haskell requires heavy lifting?

--
### SER   
### 

Re: [Haskell-cafe] embedding prolog in haskell.

2005-09-01 Thread Keean Schupke
Thanks for that, altough I have completely rewritten it! Here's the new 
implementation:


   unify :: Subst - (Term,Term) - [Subst]
   unify sigma (s,t) = let
   s' = if isVar s then subst s sigma else s
   t' = if isVar t then subst t sigma else t
   in if isVar s'  s'==t' then [sigma] else if isFunc s'  
isFunc t'

   then if fname s' == fname t'  arity s' == arity t'
   then unify' sigma (terms s') (terms t')
   else []
   else if not (isVar s)
   then unify sigma (t',s')
   else [s' ~ t' : sigma]

   unify' :: Subst - [Term] - [Term] - [Subst]
   unify' s (t0:ts) (u0:us) = case unify s (t0,u0) of
   s@(_:_) - unify' (concat s) ts us
   _ - []
   unify' s [] [] = [s]
   unify' _ _ _ = []

Once again, thoughts or improvements greatly appreciated...

   Regards,
   Keean.

Fergus Henderson wrote:


You should delete the line above.  It's not needed and could cause serious
efficiency problems.  With that line present, unifying two lists
of length N which differ only in the last element would take time
proportional to N squared, but without it, the time should be linear in N.

 


  unify s (Var x,t) = [(x,t):s] -- no occurs check
  unify s (t,Var x) = [(x,t):s] -- no occurs check
   



These are not right; you need to look up the variable x
in the substitution s, and if it is already bound, then
you need to unify what it is bound to with the term t.

 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] pros and cons of static typing and side effects ?

2005-09-01 Thread Keean Schupke

Martin Vlk wrote:


On pondělí 29 srpna 2005 8:57, Ketil Malde wrote:
 


It contains descriptions of lots of real-world problems and how
 


They are only implementing TRUTH and CWB, no?
   



Yes, and lots of real-world situations that they faced during the development. 
That's what I meant.


 


I would like to see more discussion of what is impoverished about
the environments, and what they consider mainstream programming
languages.  Certainly the authors could have discussed this in the
main part of the paper?

   


Please read section 5 in the paper.

 


I'm not sure the authors are even aware or the existence of
interactive environments (e.g. Hugs and GHCi are not mentioned, only
Haskell *compilers*).
   



I am very sure they are aware of them. Interactive interpreters are simply not 
enough of a tool for commercial development - more sophisticated tools are 
necessary. In Haskell we don't even have basic things like code structure 
visualisation, efficient browsing and fully language-aware editor with typing 
support etc.
This is one of the ways of distinguishing the mainstream languages. Mainstream 
means that enough people use them for someone to put in the effort to build 
the tools.
 

I have used IDEs (Borlands delphi, MS VisualC++), and I prefer working 
with 'vi' and multiple
shell windows. vi has such a quick startup time that you can swap 
between files easily, and it does
syntax highlighting of many languages including Haskell. Some of the 
languages mentioned (Python)
also have no real IDE, so that kind of undermines the point. I have 
written commerical code in many
languages (including Haskell) and I work the same way for all of them. 
The closest anyone in my company

comes to an IDE is python programming in Zope...

As for debugging I have yet to find a situation that a debugger handles 
better than a couple of carefully
places output statements. If you want to inspect the values of variables 
in a loop thats going wrong, just
output them, and redirect the program output to a file... you can then 
run the program and inspect the

resulting dataset to daignose the problem.

   Regards,
   Keean.




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Oracle + Haskell advice?

2005-08-19 Thread Keean Schupke
Well, I'll put my hand up, I use Haskell with databases and web stuff... 
Unfortunately when I started the common tools were not available. I have 
a home-grown Haskell-Servlet server, with monadic continuation based 
HTML composition and a HaskellDB like database layer. It all works very 
well, but being written for internal use (and me being lazy) it has only 
those features that I need. It is however designed as an integrated 
Web-Application platform... I was considering releasing it - but since I 
started other projects like HaskellDB restarted, WASH was written, HSQL 
started to support unix, and somebody added plugins to the Haskell 
Web-Server - So I didn't bother, although I am still using it myself...


Still I now know that HaskellDB has significant limitations, and the 
relational algebra approach I took is far more robust and flexable...


I don't have time to take this from a usable but incomplete project to a 
fully implemented API - what I mean here is that not all ODBC calls are 
implemented, some SQL features might be missing, some tags are not 
defined... not all HTTP requests and errors are generated, oh and 
there's no documentation. If anyone were interested in 
using/contributing I could give CVS access to the code.


   Keean.

Brian Strand wrote:



We run Suse 9.3 on x86 and x86-64; unixODBC does come out of the box 
here.  If Takusen doesn't work out for some reason, I'll check into 
HSQL + unixODBC.


Thanks for the advice,
Brian

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] embedding prolog in haskell.

2005-08-18 Thread Keean Schupke
Okay, I have found the missing definition (code was split by page 
break), and found the type error:


   type Subst = [(Var,Term)]

should be:

   type Subst = [(Vname,Term)]

And have written a simple implementation of unify from a description of 
the algorithm. I was wondering if anyone has any comments on my 
implementation of unify? For example can the algorithm be simplified 
from my nieve attempt? Most importantly is it correct?


   type Subst = [(Vname,Term)]
   data Term = Func Fname [Term] | Var Vname deriving (Eq,Show)
   type Fname = String
   data Vname = Name String | Auto Integer deriving (Eq,Show)

   unify :: Subst - (Term,Term) - [Subst]
   unify s (t,u) | t == u = [s]
   unify s (Var x,t) = [(x,t):s] -- no occurs check
   unify s (t,Var x) = [(x,t):s] -- no occurs check
   unify s (Func f ts,Func g us)
   | f == g = unify' s ts us
   | otherwise = []
  
   unify' :: Subst - [Term] - [Term] - [Subst]

   unify' s [] [] = [s]
   unify' s (t0:ts) (u0:us) = case unify s (t0,u0) of
   s@(_:_) - unify' (concat s) ts us
   _ - []

Keean.

Keean Schupke wrote:

Does anyone know if the source code for the embedded prolog (by 
Silvija Seres  Michael Spivey) is available for download from 
anywhere? I have read the paper and found some of the types are wrong, 
some critical definitions are missing, and the definition of unify is 
missing.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] embedding prolog in haskell.

2005-08-18 Thread Keean Schupke

Christian Maeder wrote:


Keean Schupke wrote:
 


implementation of unify? For example can the algorithm be simplified
from my nieve attempt? Most importantly is it correct?
   



It will not be correct without occurs check. You may also get different
terms for the same variable in your substitution list.
 


Prolog does not use an occurs check... and this is embedding prolog.
However I accept this point, thats why there was the comment about
no occurs check in the code. I actually want to cope with recursive
definitions as Prolog does, so the solution to:

   X = f(X)

should be:

   f(f(f(f(...

which is an infinite recursion.


The simplest form of unification does not take a substitution as input
and uses functions to compose two substitutions and to apply a
substitution to a term.

 


  unify :: Subst - (Term,Term) - [Subst]
   


This signature came from the paper... The input subst is an accumulator
and it would normally be Id when calling - so there is effectively no input
substitution.



Do you ever get real lists? The result type Maybe Subst is more
appropriate.
 

No, I dont think the algorithm gives real lists, Maybe would be better, 
although I
think I will get it working before playing with changing the rest of the 
code.
Is it possible to ever have more than one meaningful answer from 
unification?


 


  unify' s [] [] = [s]
  unify' s (t0:ts) (u0:us) = case unify s (t0,u0) of
  s@(_:_) - unify' (concat s) ts us
  _ - []
   



input lists of different lengths should not cause a runtime error but
only a unification failure (indicated by Nothing or [] in your case.)

 


Aha, a genuine bug... thanks!


HTH Christian

Here's a part of my version:

unify' (t0:ts) (u0:us) = do
  s1 - unify (t0,u0)
  s2 - unify' (map (applySubst s1) ts)
   (map (applySubst s1) us)
  return (composeSubst s1 s2)
 


I am now using:
  
   unify' :: Subst - [Term] - [Term] - [Subst]

   unify' s (t0:ts) (u0:us) = case unify s (t0,u0) of
   s@(_:_) - unify' (concat s) ts us
   _ - []   
   unify' s [] [] = [s]

   unify' _ _ _ = []



   Regards,
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] static typing and interactivity

2005-08-18 Thread Keean Schupke
I look at the source code and think about it... Generally I code in vi, 
then run ghci, or compile and run. I find from experience the type 
errors are normally easy to fix, you just look at the error, and study 
the structure of the function. If I still have problems I edit the code 
to return or output intermediate values. From years of doing this I can 
generally spot all my mistakes quickly... leaving only those situations 
where I don't fully understand the algorithm as requiring serious 
thought. Of course these are precisely those kind of problems for which 
a debugger is not much good either.


   Keean.




Jake Luck wrote:


One slight annoyance using Haskell is the inability to load modules
with type problems in the interactive environment (i.e. GHCi).  When I
have a type error, it would be nice to have an interactive way to
explore what the compiler thinks about the types involved -- as it is,
I have to resort to adding type signatures more or less at random to
narrow down the problem.

I'm not sure if it is technically feasible to (partially) load a
module with definitions that fail type checking, but if it were, I
thing it would make developing Haskell programs even nicer :-)



Along similiar lines, it would be quite nice if one can mark their 
haskell code(working or not) with breakpoints and drop the 
programmer into GHCi so they can poke around, especially inside a 
do-construct. e.g. something the evalutation engine can check during 
reduction maybe? I find myself writing a lot of testing frameworks, 
maybe this is a good thing!, when I program. How do most of the folks 
here debug their large code base?


jake
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] embedding prolog in haskell.

2005-08-17 Thread Keean Schupke
Does anyone know if the source code for the embedded prolog (by Silvija 
Seres  Michael Spivey) is available for download from anywhere? I have 
read the paper and found some of the types are wrong, some critical 
definitions are missing, and the definition of unify is missing.


   Regards,
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Functional Dependencies

2005-08-16 Thread Keean Schupke
Picked up on this late... I have working examples of add etc under 
ghc/ghci...
I can't remeber all the issues involved in getting it working, but I can 
post the

code for add if its any use?

   Keean.

Dirk Reckmann wrote:


Am Donnerstag, 11. August 2005 11:41 schrieb Simon Peyton-Jones:
 


You raise a vexed question, which has been discussed a lot.  Should this
typecheck?

class C a b | a - b
instance C Int Bool

f :: forall a. C Int a = a - a
f x = x

GHC rejects the type signature for f, because we can see that 'a' *must
be* Bool, so it's a bit misleading to universally quantify it.
   



Ok, maybe this is a reasonable choice. But why does the attached program work? 
ghci presents a unique type for the universal quantified function 'eight':


*Add :t eight
eight :: Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))

Best regards,
 Dirk

 


Simon

| -Original Message-
| From: [EMAIL PROTECTED]

[mailto:glasgow-haskell-users-

| [EMAIL PROTECTED] On Behalf Of Dirk Reckmann
| Sent: 21 July 2005 10:30
| To: glasgow-haskell-users@haskell.org
| Subject: Functional Dependencies
|
| Hello everybody!
|
| I wanted to have some fun with functional dependencies (see
| http://www.cs.chalmers.se/~hallgren/Papers/wm01.html), and tried some
| examples from this paper as well as some own experiments. The idea is

to use

| the type checker for computations by abuse of type classes with

functional

| dependencies.
|
| The example in the attached file is taken from the above paper. Due to

the

| functional dependencies, I expected the type of seven to be uniquely
| determined to be (Succ (Succ (Succ ...))), i. e. seven, but ghc

(version 6.4)

| gives me following error message:
|
| Add.hs:14:0:
| Couldn't match the rigid variable `a' against `Succ s'
|   `a' is bound by the type signature for `seven'
|   Expected type: Succ s
|   Inferred type: a
| When using functional dependencies to combine
|   Add (Succ n) m (Succ s), arising from the instance declaration

at

| Add.hs:11:0
|   Add (Succ (Succ (Succ Zero))) (Succ (Succ (Succ (Succ Zero

a,

| arising from the type signature for `seven' at Add.hs:13:0-77
| When generalising the type(s) for `seven'
|
| However, using the definition of Add to define Fibonacci numbers does

work,

| and a similar function declaration can be used to compute numbers by

the type

| checker.
|
| The same definition of Add works in Hugs...
|
| So, is this a bug in ghc, or am I doing something wrong?
|
| Thanks in advance,
|   Dirk Reckmann
   




{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}

module Add where

data Zero
data Succ n

class Add n m s | n m - s

instance Add Zero m m
instance Add n m s = Add (Succ n) m (Succ s)

class Fib n f | n - f

instance Fib Zero (Succ Zero)
instance Fib (Succ Zero) (Succ Zero)
instance (Fib n fib_n,
 Fib (Succ n) fib_s_n,
 Add fib_n fib_s_n sum
) = Fib (Succ (Succ n)) sum

eight :: Fib (Succ (Succ (Succ (Succ (Succ Zero) n = n
eight = undefined
   




___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
   



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Re: [Haskell] pros and cons of static typing and side effects ?

2005-08-16 Thread Keean Schupke

My 2-pence worth on static typing.

Static typing to me seems to be a simplified form of design by contract. 
There are some things about a program that can be proved true for all 
time. Types are an example of such a thing. We can use type systems to 
make assertions about properties that must be true for all time, and 
then reject programs that break these rules.


One of the easyest things to prove about a program is that all values 
and references are handled correctly - hence you will never see a 
segmentation fault due to bad programming, it is just impossible (of 
course the run-time-system which is written in C may cause one, but that 
cannot be due to a bug in your program).



Taking one of your points in more detail:The single type property for 
lists is not a problem due to the presence of algebraic datatypes, for 
example want a list of strings and ints:


   data StringOrInt = IsString String | IsInt Int
   type ListOfStringOrInt = [StringOrInt]

You can also have lists of records... Think about it for a bit and you 
will see there are very  few cases where you need to have a list of 
'general types'...


You can even use existential types to create lists of things with a 
common interface, where you do not know in advance what types you may need:


   data XWrap = XWrap (forall a . Show a = a)
   type ListXWrap = [XWrap]

This creates a list where the items can be any type, provided they are a 
member of the class Show. Also the only functions you can call on the 
items in the list are the methods of the Show class... Of course you can 
have multiple type constraints (forall a . (Show a,Num a) = a).


This is not the limit of how far we can go with static typing. We can 
choose any provable property about a program... for example we could ask 
that the compiler prove that the heap size of the program never exceeds 
10M (not possible in any current language - but is an extension of the 
concept).


Other things we can do ... with dependant types we can ask the compiler 
to prove the correctness of sorting algorithms. If we define an ordered 
list tgo be one where each element must be larger than the preceding one:


   data OrderedIntList = Cons (a::Int) (l::OrderedList) | Nil {- where 
a = head l -}

   data IntList = [Int]

We can now define our sorting function:

   quicksort :: IntList - OrderedIntList

By this we are asking the compiler to prove (by induction) that the 
function provided can only result in
correctly ordered lists - irrespective of what arguments it is given (ie 
proved true for any input)... This would have to be done symbolically 
but is not beyond what can be achieved using logic programming.
To implement this, a Prolog program containing all the type constraints 
of the function definition and
the proposed type would be evaluated... Prolog will say yes or no 
to the function.


   Regards,
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] pros and cons of static typing and side effects ?

2005-08-16 Thread Keean Schupke

Benjamin Franksen wrote:


On Tuesday 16 August 2005 21:56, Keean Schupke wrote:
 


You can even use existential types to create lists of things with a
common interface, where you do not know in advance what types you may
need:

   data XWrap = XWrap (forall a . Show a = a)
   type ListXWrap = [XWrap]
   



You probably meant to write

   data XWrap = forall a . Show a = XWrap a

or, in GADT style (which I find a bit more intuitive here):

   data XWrap where
 XWrap :: Show a = a - XWrap

 


Yes I always get confused by the notation Haskell uses... I used explicit
universal quantification by mistake. I tried to think logically about 
the encapsulation

existential types represent - and got the wrong form.

I for one would like to see the use of 'exists' as a keyword for 
existential types, after
all different symbols are used in modal logic (upside-down-A for forall, 
and backwards-E

for exists).

   Regards,
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] pros and cons of static typing and side effects ?

2005-08-16 Thread Keean Schupke

Lennart Augustsson wrote:


Keean Schupke wrote:



   quicksort :: IntList - OrderedIntList

By this we are asking the compiler to prove (by induction) that the 
function provided can only result in
correctly ordered lists - irrespective of what arguments it is given 
(ie proved true for any input)... This would have to be done 
symbolically but is not beyond what can be achieved using logic 
programming.



But the output being ordered is not enough.  The output should also
be a permutation of the input.  This can, of course, be expressed
in a similar way.


Yes, the easiest way would be to constrain the output list to be a subset of
the input list, and vice-versa... something like:

   quicksort :: (x::IntList) - (y::OrderedIntList) {- where x : y  
x : y -}


of course you would have to use the correct definition of subset - you 
really want to

treat the list as a multi-set.

   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] pros and cons of static typing and side effects ?

2005-08-16 Thread Keean Schupke

Benjamin Franksen wrote:



as in

 data XWrap = Show a = XWrap a

I always thought this was a pretty nice idea.

 

Wow, I hadn't thought of that... of course you still need to explicitly 
give the
universal quantification if you need it. I guess the best option is to 
make it

optional, as I still like the look of:

   data XWrap = exists a . Show a = XWrap a

It kind of say this is existential quantification in large freindly 
letters...

(A bit like a book I once read - except that said Don't Panic)

   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:

My objections to making everything a matrix were the objections I sketched
for MatLab.

The example, again: If you write some common expression like

transpose x * a * x
  

Which just goes to show why haskell limits the '*' operator to
multiplying the same types. Keep this to Matrix-times-Matrix operators.

Surely a vector is a 1xN matrix? And in terms of matrices a 1x1 matrix
and a scalar are the same? I don't see the point of having separate
matix and vector types... just have 'matrix constructors:

matrix :: [[a]] - Matrix a
vector :: [a] - Matrix a
scalar :: a - Matrix a

I don't see any problems with this, and it lets you define the matrix
exponential:

instance Floating a = Floating (Matrix a) where
exp = undefined

Type of exp in Floating is (a - a - a), so substituting the class
parameter gives:
exp :: Matrix a - Matrix a - Matrix a, however you can only compute
the matrix exponential
(x^y) for scalar-x matrix-y or matrix-x scalar-y...

I feel using separate types for vectors and scalars just overcomplicates
things...

then both the human reader and the compiler don't know whether x is a
true matrix or if it simulates a column or a row vector. It may be that
'x' is a row vector and 'a' a 1x1 matrix, then the expression denotes a
square matrix of the size of the vector simulated by 'x'. It may be that
'x' is a column vector and 'a' a square matrix. Certainly in most cases I
want the latter one and I want to have a scalar as a result. But if
everything is a matrix then I have to check at run-time if the result is a
1x1 matrix and then I have to extract the only element from this matrix.
If I omit the 1x1 test mistakes can remain undiscovered. I blame the
common notation x^T * A * x for this trouble since the alternative
notation x, A*x can be immediately transcribed into computer language
code while retaining strong distinction between a vector and a matrix
type.
  

If x is a matrix and y is a matrix then

x * y

can only be interpreted in one simple way - no special cases. Sometimes you
may need to transpose a 1xN into an Nx1 but at least you will get an
'error' if you
try to use the wrong type...

More examples? More theory?
  

More complexity?

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:


Let me elaborate on that:
 In some cases putting vectors as columns into a matrix then applying a
matrix operation on this matrix leads to the same like to 'map' a
matrix-vector operation to a list of vectors. But in other cases (as the
one above) this is not what you want. I consider it as an incidence not as
a general principle if this kind of extension works.

Let's consider another example: The basic definition of the Fourier
transform is for vectors. MatLab wants to make the effect of vector
operations consistent for row and column vectors, thus
  

Okay, this approach is starting to make sense to me... I can see now that
Vectors are a different type of object to Matrices. Vectors represent
points in
N-Space and matrices represent operations on those points (say rotations or
translations)...

But it seems we can represent translations as adding vectors or matrix
operations
(although we need to introduce the 'extra' dimension W... and have an
extra field in vectors
that contains the value '1').

(3D translation)

[x,y,z,1] * [[0,0,0,0],[0,0,0,0],[0,0,0,0],[dx,dy,dz,dw]] =
[x+dx,y+dy,z+dz,1+dw]

but how is this different from adding vectors? If we allow vector
addition then we no longer
have the nice separation between values and linear operators, as a value
can also be
a linear operator (a translation)?

Keean.



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:


I'm excited if your code gets swamped by conversions between Double and
Matrix then. I really plead for representing everything with strings, this
is the most simple and most flexible solution! :-]
  

Surely its a case of balancing the advantage of type safety against the
added complexity. The point after all is to reduce bugs. Type-sigs reduce
one type of bug, at the cost of an increase in complexity. My argument is
that at some point the probability of introducing errors due to the
increased
complexity outweighs the reduction in the probability of error due to
type-safety?

I think this is a pragmatic point, that cannot be argued with, all you
can argue over
is where in the continuum this point is.

As such we were dicussing the complexity/type-safety trade off with
respect to
matrices - to go from this to such a sweeping statment... is like saying
'if I can't have it my way I don't want anything at all...

Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:


Do you mean
 [x,y,z,1] * [[1,0,0,0],[0,1,0,0],[0,0,1,0],[dx,dy,dz,dw+1]]
?

  

Erm, yes thats what I meant ... but you obviously got the point.

but how is this different from adding vectors? If we allow vector
addition then we no longer have the nice separation between values and
linear operators, as a value can also be a linear operator (a
translation)?



???

  

Well if a vector can be a linear-operator, then surely it _is_ a matrix!

Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Is a matrix is a linear operation on a vector, does it not make sense to
define matrix applicaion:

mapply :: Matrix - Vector - Vector

Then you can define say:

rotate90 = mapply rotationMatrix90

v' = rotate90  v


Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:



In general a vector need not to be a linear operator. You talked about
vector translation, translation is not a linear operator. You gave some
process to map the problem to somewhere, where it becomes a linear
operator. Other people said that the scalar product with a fixed vector is
a linear operator. That's true. Now what is a natural interpretation of a
vector as linear operator? The scalar product or the translation? Vectors
can be used and abused for many things but an object which can be called a
vector (because of its ability of to be added and to be scaled) is not a
linear operator itself and does not naturally represent one.

  

So the linear operator is translation (ie: + v)... effectively 'plus'
could be
viewed as a function which takes a vector and returns a matrix (operator)

(+) :: Vector - Matrix

Which could also be called 'translate'. So 'translate' takes a vector
and returns
a linear-operator which can be applied to a vector:

mapply (translate vector1) vector2

So I guess I could now ask, why allow vector addition at all?

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:

On Fri, 8 Jul 2005, Keean Schupke wrote:

  

So the linear operator is translation (ie: + v)... effectively 'plus'
could be viewed as a function which takes a vector and returns a matrix
(operator)

(+) :: Vector - Matrix



Since a matrix _is_ not a linear map but only its representation, this
would not make sense. As I said (v+) is not a linear map thus there is no
matrix which represents it. A linear map f must fulfill
 f 0 == 0

But since
 v+0 == v
  the function (v+) is only a linear map if 'v' is zero.

 I can't see how to fit in your vector extension by the 1-component.

  

Eh?

Translation is a linear operation no? Adding vectors translates the
first by the second
(or the second by the first - the two are isomorphic)... A translation
can be represented
by the matrix:

1   0   0   0
0   1   0   0
0   0   1   0
dx dy dz 1

So the result of v+ is this matrix.

In other words this matrix is the 'vector addition operator'...
providing you pad the vectors
with an additional '1' at the end.

So if:

translate :: Vector - Matrix

[x,y,z,1] = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[x,y,z,1]]

 we can create a matrix representing translation from:

translate [3,4,5,1]

and can apply this translation to another vector:

mapply (translate [3,4,5,1]) [2,3,4,1] = [5,7,9,1]


All I was saying is that following this, partial application of vector
addition:

[3,4,5] + [2,3,4] = [5,7,9]

but partially applying:

([3,4,5] +)

would be a the matrix defined above as (translate [3,4,5,1]) ... Of
course this has the
drawback that you need an extra dimension in you vectors and matrices to
cope with
translation.


Anyway I have more or less convinced myself that separating vectors and
matrices is the
right thing to do... I was just trying to define vector addition in
terms of a matrix operation
for neatness.

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: matrix computations based on the GSL

2005-07-08 Thread Keean Schupke
Henning Thielemann wrote:

does it not make sense to define matrix applicaion:

mapply :: Matrix - Vector - Vector

Then you can define say:

rotate90 = mapply rotationMatrix90

v' = rotate90  v



... that's what I said about mulVec.
  

I guess that means we agree...

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-05 Thread Keean Schupke
Henning Thielemann wrote:

I'm uncertain about how who want to put the different kinds of
multiplication into one method, even with multi-parameter type classes.
You need instances

 (*) :: Matrix - Matrix - Matrix
 (*) :: RowVector - Matrix - RowVector
 (*) :: Matrix - ColumnVector - ColumnVector
 (*) :: RowVector - ColumnVector - Scalar
 (*) :: ColumnVector - RowVector - Matrix
 (*) :: Scalar - RowVector - RowVector
 (*) :: RowVector - Scalar - RowVector
 (*) :: Scalar - ColumnVector - ColumnVector
 (*) :: ColumnVector - Scalar - ColumnVector

but you have to make sure that it is not possible to write an expression
which needs
 (*) :: Matrix - RowVector - RowVector

Further you need
 transpose :: RowVector - ColumnVector
 transpose :: ColumnVector - RowVector
 transpose :: Matrix - Matrix
and you must forbid, say
 transpose :: RowVector - RowVector
  

Of course if they are all of type Matrix this problem disappears. What
is the
difference between a 1xN matrix and a vector? Please explain...

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] matrix computations based on the GSL

2005-07-05 Thread Keean Schupke
David Roundy wrote:

In short, especially since the folks doing the work (not me) seem to want
plain old octave-style matrix operations, it makes sense to actually do
that.  *Then* someone can implement an ultra-uber-tensor library on top of
that, if they like.  And I would be interested in a nice tensor
library... it's just that matrices need to be the starting point, since
they're where most of the interesting algorithms are (that is, the ones
that are interesting to me, such as diagonalization, svd, matrix
multiplication, etc).
  

This is a really good idea. I would like a Matrix library soon, not in 6
years time.
Slice it up into managable pieces and keep it simple!

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re[4]: [Haskell] Dynamic binding

2005-06-23 Thread Keean Schupke
Interestingly this is exactly the approach taken in the OOHaskell paper!
The difference is we used extensible records with subtyping (from the
HList paper)
to implement inheritance and overloading, which you cannot do with ordinary
Haskell records.

So you statment that it is better to do it in Haskell, well we are both
doing it in
Haskell, and your proposed method is just a simplified version of what
we are
doing in the paper.


Keean.


Bulat Ziganshin wrote:

Hello Ralf,

Thursday, June 23, 2005, 11:36:20 AM, you wrote:

  

just create list of draw functions itself:

[drawCircle (10,10) 5, drawSquare (20,20) 10]
  


RL No! the exercise is about lists of shapes
RL not lists of results of drawing shapes.
RL This is clearly a major difference.

in cases where you need to call only one function on created objects,
you can just insert in list calls to this functions (not their results! i 
suppose
that drawXXX functions has ... - IO () type)

in cases where you need to call several functions for this object, you
can insert in list tuple or structure for each object, as i do in next
example. original exercise was about OO way to solve some problem. i want
to say that in Haskell it's better in most cases to use another,
functional way

RL Bulat wrote:

  

for more complex tasks - declare interface as a structure:

data ShapeInterface = Shape { draw :: IO (),
  moveTo :: Point - IO (),
  calcArea :: Float
}
  


RL No! You miss the point that the different shapes
RL differ regarding state types.
RL You don't have a chance when you use one datatype.

this state is just don't need to appear in interface definition :)

see for example:

data ShapeInterface = Shape { draw :: IO (),
  calcArea :: Float
}

circle x y r = Shape { draw = drawCircle x y r,
   calcArea = pi*r*r
 }

square x y size = Shape { draw = drawSquare x y size,
  calcArea = size*szie
}

figures = [circle 1 2 3, square 4 5 6, circle 7 8 9]





if you need to maintain mutable state, this is also not a problem:

data ShapeInterface = Shape { draw :: IO (),
  moveTo :: (Int,Int) - IO (),
  calcArea :: Float
}
circle x y r = do
  center - ref (x,y)
  return Shape { draw = val center = drawCircle r
   , moveTo   = (center=:)
   , calcArea = pi*r*r
   }
main = do
  figures - sequence [circle 1 2 3, square 4 5 6, circle 7 8 9]
  mapM_ draw figures
  mapM_ (moveTo (0,0)) figures
  mapM_ draw figures

ref=newIORef
val=readIORef
(=:)=writeIORef


RL haskell-cafe?

as you wish :)

  


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


using the Intel compiler (icc)

2005-06-05 Thread Keean Schupke
Is it possible to get GCC to use the intel C compiler (ICC) instead of gcc?

Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: using the Intel compiler (icc)

2005-06-05 Thread Keean Schupke
Sorry, yes I mean getting GHC to use ICC instead of GCC... is it just a
matter of a command line switch to give GHC the path to the compiler?

Keean.

Seth Kurtzberg wrote:

 Keean Schupke wrote:

Is it possible to get GCC to use the intel C compiler (ICC) instead of gcc?
  

 Do you mean is it possible to get /GHC/ to use /ICC/?  Otherwise I
 don't understand the question.

Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

  



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Open mutable records

2005-05-23 Thread Keean Schupke
Have you seen the OOHaskell paper (the follow up to the HList paper)...
It looks like
you do much the same thing - with some differences... Would be
interesting to get your
comments on the paper:

http://homepages.cwi.nl/~ralf/OOHaskell/

Keean.

Einar Karttunen wrote:

Hello

I recently ended up hacking a quite concise implementation of
mutable open (extensible) records in Haskell. Most of the ideas 
came from the HList-paper, but this seems like a very simple way of
doing things.

Run with ghci -fglasgow-exts -fallow-overlapping-instances.

Import some stuff we are going to need later:

  

import Control.Monad.Reader
import Data.IORef
import System



Monad for mutable record calculations - to get implisit this/self in the
OO sense.

  

newtype OO t r = OO (ReaderT t IO r) deriving(Monad, MonadReader t, MonadIO)

with :: s - OO s a - OO b a
with this (OO c) = liftIO (runReaderT c this)

ooToIO :: OO s a - IO a
ooToIO (OO c) = runReaderT c undefined



Records

First the record constructor - followed by the terminator.

  

data a :.: r = RC !a !r
infixr :.:
data END = END



Next we define a field access method.

  

class Select r f t | r f - t where (!) :: r - f - Ref t
instance Select (Field f t :.: r) f t where (!) (RC (F x) _) _ = x
instance Select r f t = Select (a :.: r) f t where (!) (RC _ t) = (!) t



And finally the type of mutable fields.

  

type Ref a = IORef a
newtype Field name rtype = F (Ref rtype)



Next we define a way to construct record values.

  

infixr ##
(##) :: v - OO s r - OO s ((Field f v) :.: r)
(##) v r = do { h - liftIO (newIORef v); t - r; return (RC (F h) t) }
end = return END :: OO s END



Get the value of a field.

  

value :: Select s f t = f - OO s t
value a  = do x - asks (\s - s!a) 
  liftIO (readIORef x)



Or set the value of a field.

  

(-:) :: Select s f t = f - t - OO s () 
a -: b  = do x - asks (\s - s!a)
  liftIO (writeIORef x b)



And as a convenience add value to an int field.

  

(+=) :: Select s f Int = f - Int - OO s Int
a += b   = do x - asks (\s - s!a)
  val - liftIO (readIORef x)
  let z = val+b
  z `seq` liftIO (writeIORef x z)
  return z



Now implement the classic ocaml OO tutorial:

  

data X = X
type Point = Field X Int :.: END

newPoint :: OO s Point
newPoint = 0 ## end

getX :: Select s X t = OO s t
getX = value X

move d = X += d



  

data Color = Color
type ColoredPoint = Field Color String :.: Point

newColoredPoint :: String - OO s ColoredPoint
newColoredPoint c = c ## 0 ## end

color :: Select s Color t = OO s t
color = value Color



The code looks in more complex examples like this:
((~=) is prepending into list fields.)

newArrival :: Patient - OO Hospital ()
newArrival patient = do
  with patient (HospitalVisits += 1)
  staff - value FreeStaff
  if staff  0 then do FreeStaff += (-1)
   Examination ~= patient
   with patient (do HospitalTime += 3
RemainingTime -: 3)
   else do Triage ~= patient


  

main = ooToIO (do c1 - newPoint
  c2 - newColoredPoint green
  with c1 $ move 7
  with c2 $ move 4
  let p x = liftIO (print x)
  p = with c1 getX
  p = with c2 getX)




- Einar Karttunen
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
  


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell] Eternal Compatibility In Theory

2005-05-03 Thread Keean Schupke
robert dockins wrote:

 Is there a way to reliably and automatically check if two versions of
 a haskell module are interface compatible?

  
 No, because it would have to check whether the semantics of functions
 is the same, even if they are written differently.


 Of course, we cannot expect the computer to examine the semantics.  We
 must rely on people to know when semantics change.

 Suppose I want to ask the easier question do these two text files
 implement haskell modules which are _type_ compatable?, how would I
 do it?  Ie, I want the test to fail if I change the type of some
 function foo, or if I add a method to a class declaration etc.


 ___
 Haskell mailing list
 Haskell@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell

Is this true? Can't you use an IDL to specify the interface more
exactly. I would have thought a definition of the protocol was enough.

If you define a protocol definition language then it should be possible
to check both ends of the connection to see if the conform to the protocol.

Keean.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] RFE: Extensible algebraic user-defined data types?

2005-04-29 Thread Keean Schupke
David Menendez wrote:
The downside is that a function that might normally be typed Either A B
- C now will have the type:
   (HTypeIndexed l,
HTypeProxied l,
HOccurs (Proxy (Left A)) l,
HOccurs (Proxy (Right B)) l) =
   TIC l - C
   
But it will accept a TIC (HEither A B) and a TIC (HNEither A B) and any
other TIC that contains Left A and Right B among its possible values.

[1] http://homepages.cwi.nl/~ralf/HList/
 

Of course the compiler will infer this type for you. I find it very 
handy to use explicitly typed funtions to compose constraints, thus 
avoiding the need to have big type signatures... something like:

constrainInt :: Int - Int
constrainInt = id
constrainSomeClass :: SomeClass a = a - a
constrainSomeClass = id
you can then write:
f i c = someFn (constrainInt i) (constrainSomeClass c)
Where someFn has a complicated type like that above...
In this way you can avoid having to specify all the constraints a 
function, and it effectively gives you the same functionality as partial 
type signatures.

   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Instances of constrained datatypes

2005-04-08 Thread Keean Schupke
Can you not define functor like Hughes defines a restricted monad 
(section 3 in the paper)...

   Keean
Arjun Guha wrote:
One way to do roughly what you want is to pass the dictionary yourself:
 data EqDict a = EqDict {
  leq :: a - a - Bool }
  
  data EqList a = EqList (EqDict a) [a]
  
  test :: EqList a - EqList a - Bool
  test (EqList dict (a0:as)) (EqList _ (b0:bs)) = (leq dict) a0 b0

This is like the `object-oriented approach' in John Hughes' paper.  
Let's switch to the set example in his paper:

 data EqDict a = EqDict { isEq:: a - a - Bool }
 data Set a = Set (EqDict a) [a]
So, to make it a functor, as I originally wanted:
 instance Functor Set where
   fmap f (Set dict ls) = Set dict' ls' where
 ls' = nubBy (isEq dict') ls
 dict' = ???
There really isn't a way to define dict' for the resultant Set.
-Arjun

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] List containing different types but all implementing the same class

2005-04-08 Thread Keean Schupke
You can do this like:
data TTrue = TTrue
data TFalse = TFalse

data Nil = Nil
data Cons a l = Cons a l

class Constrain c a b | c a - b where
constrain :: c - a - b

data ZConstraint = ZConstraint
instance Z a b = Constrain ZConstraint a b

class List c l
instance List c Nil
instance (Constrain c a TTrue,List c l) = List c (Cons a l)
Now define a class 'Z' using a fundep such that 'b' becomes TTrue if 'a' 
is in Z.

class Z a b | a - b where
instance (TypeEq a Int b,TypeEq a Float b,TOr a b c) = Z a c
 -- Int and Float are members of Z, TypeEq and TOr come from the
 -- HList library.
Finally you can constrain the list:
f :: List ZConstraint l - List ZConstraint l
f x = x
   Regards,
   Keean.
Bo Herlin wrote:
Hi everyone. Being new to Haskell I wonder how I can make a list 
contain different types but all implementing the same class, like this:

data X = X
data Y = Y
class Z a where f :: a - Int
instance Z X where f x = 0
instance Z Y where f y = 1
test1 :: Z a = [a]
test1 = [X,Y]
test2 = map f test1
Is it possible to make this work?
/Bo Herlin
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Instances of constrained datatypes

2005-04-07 Thread Keean Schupke
I think it is more a problem of imlpementation than one of what is 
desirable. A Constrained data type:

data (Eq v) = EqList v = EqList [v]
The problem is how to get the dictionary for the class Eq to the 
application site:

f :: EqList v - EqList v
f (EqList (u0:us)) (EqList (v0:vs)) | v0 == u0 = ...
Which of course does not work... the constraint needs to be in the function
type signature:
f :: Eq v = EqList v - EqList v
Things are worse though, as even functions that use no methods of Eq will
require the constraint.
The constraint on the data type does not stop you construction EqLists from
non Eq members... of course this gets detected the moment you try and use it
in a constrained function.
In other words using the constraint in the data type does nothing... you 
may as well just do:

f :: Eq v = [v] - [v]
Infact I believe it was decided to remove the feature from Haskell98 
entirely, but there was apparently some use for the 'syntax' although 
with a different effect.

   Keean.
Cale Gibbard wrote:
I don't believe you can, but it would be nice. There are certain
types, such as Set, where it's not really possible to just remove the
constraint from the data declaration, and yet it would be nice if sets
could be instances of Monad and Functor. Currently, to be an instance
of Functor or Monad, your type has to be a functor defined on the
whole category of types.
Could this issue be fixed somehow? Constrained instances would make
various typeclass-based libraries more applicable. What would it break
to allow instances where the types of functions defined by the
typeclass are further restricted? I suppose that checking that types
are correct becomes more difficult and non-local, because  functions
which are defined using the typeclass won't already have that
constraint for obvious reasons. Still, the constraint is in the
instance, which must be around when the functions actually get
applied. There are probably bad interactions with the module system,
but I'm not certain.
People must have talked about this before... was a consensus reached
that I'm not aware of?
- Cale
On Apr 6, 2005 2:10 AM, Arjun Guha [EMAIL PROTECTED] wrote:
 

This is a contrived example, but contains the essence of what I'd like
to do.  Suppose I have this datatype:
 data (Eq v) = EqList v = EqList [v]
I'd like to make it an instance of Functor.  However, fmap takes an
arbitrary function  of type a - b.  I need an Eq constraint on a and
b.  Is there any way to do this without creating my own `EqFunctor'
class with explicitly-kinded quantification:
 class (Eq a) = EqFunctor (f :: * - *) a where
  eqfmap:: (Eq b) = (a - b) - f a - f b
Thanks.
-Arjun
   

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Instances of constrained datatypes

2005-04-07 Thread Keean Schupke
One way to do roughly what you want is to pass the dictionary yourself:
data EqDict a = EqDict {
leq :: a - a - Bool }

data EqList a = EqList (EqDict a) [a]

test :: EqList a - EqList a - Bool
test (EqList dict (a0:as)) (EqList _ (b0:bs)) = (leq dict) a0 b0
In this way the definition of equality on elements of type 'a' is passed 
with the list type, so it can be used wherever the list type is used, 
without requiring extra constraints.

   Keean.
Keean Schupke wrote:
I think it is more a problem of imlpementation than one of what is 
desirable. A Constrained data type:

data (Eq v) = EqList v = EqList [v]
The problem is how to get the dictionary for the class Eq to the 
application site:

f :: EqList v - EqList v
f (EqList (u0:us)) (EqList (v0:vs)) | v0 == u0 = ...
Which of course does not work... the constraint needs to be in the 
function
type signature:

f :: Eq v = EqList v - EqList v
Things are worse though, as even functions that use no methods of Eq will
require the constraint.
The constraint on the data type does not stop you construction EqLists 
from
non Eq members... of course this gets detected the moment you try and 
use it
in a constrained function.

In other words using the constraint in the data type does nothing... 
you may as well just do:

f :: Eq v = [v] - [v]
Infact I believe it was decided to remove the feature from Haskell98 
entirely, but there was apparently some use for the 'syntax' although 
with a different effect.

   Keean.
Cale Gibbard wrote:
I don't believe you can, but it would be nice. There are certain
types, such as Set, where it's not really possible to just remove the
constraint from the data declaration, and yet it would be nice if sets
could be instances of Monad and Functor. Currently, to be an instance
of Functor or Monad, your type has to be a functor defined on the
whole category of types.
Could this issue be fixed somehow? Constrained instances would make
various typeclass-based libraries more applicable. What would it break
to allow instances where the types of functions defined by the
typeclass are further restricted? I suppose that checking that types
are correct becomes more difficult and non-local, because  functions
which are defined using the typeclass won't already have that
constraint for obvious reasons. Still, the constraint is in the
instance, which must be around when the functions actually get
applied. There are probably bad interactions with the module system,
but I'm not certain.
People must have talked about this before... was a consensus reached
that I'm not aware of?
- Cale
On Apr 6, 2005 2:10 AM, Arjun Guha [EMAIL PROTECTED] wrote:
 

This is a contrived example, but contains the essence of what I'd like
to do.  Suppose I have this datatype:
 data (Eq v) = EqList v = EqList [v]
I'd like to make it an instance of Functor.  However, fmap takes an
arbitrary function  of type a - b.  I need an Eq constraint on a and
b.  Is there any way to do this without creating my own `EqFunctor'
class with explicitly-kinded quantification:
 class (Eq a) = EqFunctor (f :: * - *) a where
  eqfmap:: (Eq b) = (a - b) - f a - f b
Thanks.
-Arjun
  

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Instances of constrained datatypes

2005-04-07 Thread Keean Schupke
One way to do roughly what you want is to pass the dictionary yourself:
data EqDict a = EqDict {
leq :: a - a - Bool }

data EqList a = EqList (EqDict a) [a]

test :: EqList a - EqList a - Bool
test (EqList dict (a0:as)) (EqList _ (b0:bs)) = (leq dict) a0 b0
In this way the definition of equality on elements of type 'a' is passed 
with the list type, so it can be used wherever the list type is used, 
without requiring extra constraints.

  Keean.
Keean Schupke wrote:
I think it is more a problem of imlpementation than one of what is 
desirable. A Constrained data type:

data (Eq v) = EqList v = EqList [v]
The problem is how to get the dictionary for the class Eq to the 
application site:

f :: EqList v - EqList v
f (EqList (u0:us)) (EqList (v0:vs)) | v0 == u0 = ...
Which of course does not work... the constraint needs to be in the 
function
type signature:

f :: Eq v = EqList v - EqList v
Things are worse though, as even functions that use no methods of Eq will
require the constraint.
The constraint on the data type does not stop you construction EqLists 
from
non Eq members... of course this gets detected the moment you try and 
use it
in a constrained function.

In other words using the constraint in the data type does nothing... 
you may as well just do:

f :: Eq v = [v] - [v]
Infact I believe it was decided to remove the feature from Haskell98 
entirely, but there was apparently some use for the 'syntax' although 
with a different effect.

   Keean.
Cale Gibbard wrote:
I don't believe you can, but it would be nice. There are certain
types, such as Set, where it's not really possible to just remove the
constraint from the data declaration, and yet it would be nice if sets
could be instances of Monad and Functor. Currently, to be an instance
of Functor or Monad, your type has to be a functor defined on the
whole category of types.
Could this issue be fixed somehow? Constrained instances would make
various typeclass-based libraries more applicable. What would it break
to allow instances where the types of functions defined by the
typeclass are further restricted? I suppose that checking that types
are correct becomes more difficult and non-local, because  functions
which are defined using the typeclass won't already have that
constraint for obvious reasons. Still, the constraint is in the
instance, which must be around when the functions actually get
applied. There are probably bad interactions with the module system,
but I'm not certain.
People must have talked about this before... was a consensus reached
that I'm not aware of?
- Cale
On Apr 6, 2005 2:10 AM, Arjun Guha [EMAIL PROTECTED] wrote:
 

This is a contrived example, but contains the essence of what I'd like
to do.  Suppose I have this datatype:
 data (Eq v) = EqList v = EqList [v]
I'd like to make it an instance of Functor.  However, fmap takes an
arbitrary function  of type a - b.  I need an Eq constraint on a and
b.  Is there any way to do this without creating my own `EqFunctor'
class with explicitly-kinded quantification:
 class (Eq a) = EqFunctor (f :: * - *) a where
  eqfmap:: (Eq b) = (a - b) - f a - f b
Thanks.
-Arjun
  

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Functional dependencies, principal types, and decidable typechecking

2005-04-06 Thread Keean Schupke
Manuel M T Chakravarty wrote:
I accept that this is the process by which GHC computes these types, but
it does violate the principal types property, doesn't it?  The relation
 Int - ()   =   forall c. Int - c
does not hold.
 

I realise that principal types and principal typings are slightly 
different, but I was
wondering if the fact that it has recently been shown that 
Hindley/Milner does not
have principal typings has any meaning here?

Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Oops [Fwd: Re: Allowing duplicate instances in GHC 6.4]

2005-03-31 Thread Keean Schupke
Robert van Herk wrote:
Sorry, this is the compiler error I get:
No instances for (KeyHasValue MyKeyVal k' v',
 Datasource.Tools.FakePrelude.TypeEq Float k' z,
 Datasource' z [MyKeyVal] [MyKeyVal] Float Int)
When I am trying to do
 do { createJoinedDS' x x;
 (joined,(v::Maybe Int)) - _dsread joined (2.0::Float);
  }
Robert

Subject:
Re: Allowing duplicate instances in GHC 6.4
From:
Robert van Herk [EMAIL PROTECTED]
Date:
Thu, 31 Mar 2005 16:49:07 +0200
To:
glasgow-haskell-users@haskell.org
To:
glasgow-haskell-users@haskell.org
Return-Path:
[EMAIL PROTECTED]
X-Original-To:
[EMAIL PROTECTED]
Delivered-To:
[EMAIL PROTECTED]
Received:
from mail.students.cs.uu.nl (localhost.localdomain [127.0.0.1]) by 
mail.students.cs.uu.nl (Postfix) with ESMTP id 85339225D8C for 
[EMAIL PROTECTED]; Thu, 31 Mar 2005 16:54:12 +0200 (CEST)
Received:
from mail.cs.uu.nl (dusk.cs.uu.nl [131.211.80.10]) by 
mail.students.cs.uu.nl (Postfix) with ESMTP id 68C95225D84 for 
[EMAIL PROTECTED]; Thu, 31 Mar 2005 16:54:12 +0200 (CEST)
Received:
by mail.cs.uu.nl (Postfix) id EF0D9A35E2; Thu, 31 Mar 2005 16:54:11 
+0200 (CEST)
Delivered-To:
[EMAIL PROTECTED]
Received:
from mail.cs.uu.nl (localhost.localdomain [127.0.0.1]) by 
mail.cs.uu.nl (Postfix) with ESMTP id D9C06A35F7; Thu, 31 Mar 2005 
16:54:11 +0200 (CEST)
Received:
from www.haskell.org (bugs.haskell.org [128.36.229.215]) by 
mail.cs.uu.nl (Postfix) with ESMTP id 99FA2A35E2; Thu, 31 Mar 2005 
16:54:11 +0200 (CEST)
Received:
from haskell.cs.yale.edu (localhost.localdomain [127.0.0.1]) by 
www.haskell.org (Postfix) with ESMTP id 666A436825E; Thu, 31 Mar 2005 
09:36:48 -0500 (EST)
X-Original-To:
glasgow-haskell-users@haskell.org
Delivered-To:
glasgow-haskell-users@haskell.org
Received:
from mail.cs.uu.nl (dusk.cs.uu.nl [131.211.80.10]) by www.haskell.org 
(Postfix) with ESMTP id 3A87D368106 for 
glasgow-haskell-users@haskell.org; Thu, 31 Mar 2005 09:36:45 -0500 
(EST)
Received:
from mail.cs.uu.nl (localhost.localdomain [127.0.0.1]) by 
mail.cs.uu.nl (Postfix) with ESMTP id 16C67A35F7; Thu, 31 Mar 2005 
16:54:05 +0200 (CEST)
Received:
from [131.211.84.110] (mckroket.labs.cs.uu.nl [131.211.84.110]) by 
mail.cs.uu.nl (Postfix) with ESMTP id 0635AA35E2; Thu, 31 Mar 2005 
16:54:05 +0200 (CEST)
Message-ID:
[EMAIL PROTECTED]
User-Agent:
Mozilla Thunderbird 1.0 (Macintosh/20041206)
X-Accept-Language:
en-us, en
MIME-Version:
1.0
References:
[EMAIL PROTECTED] [EMAIL PROTECTED] 
[EMAIL PROTECTED] [EMAIL PROTECTED] 
[EMAIL PROTECTED] [EMAIL PROTECTED]
In-Reply-To:
[EMAIL PROTECTED]
Content-Type:
text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding:
7bit
X-AV-Checked:
ClamAV using ClamSMTP at cs.uu.nl
X-BeenThere:
glasgow-haskell-users@haskell.org
X-Mailman-Version:
2.1.5
Precedence:
list
List-Id:
The Glasgow Haskell Users Mailing List 
glasgow-haskell-users.haskell.org
List-Unsubscribe:
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users, 
mailto:[EMAIL PROTECTED]
List-Archive:
http://www.haskell.org//pipermail/glasgow-haskell-users
List-Post:
mailto:glasgow-haskell-users@haskell.org
List-Help:
mailto:[EMAIL PROTECTED]
List-Subscribe:
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users, 
mailto:[EMAIL PROTECTED]
Sender:
[EMAIL PROTECTED]
Errors-To:
[EMAIL PROTECTED]
X-AV-Checked:
ClamAV using ClamSMTP at cs.uu.nl
X-AV-Checked:
ClamAV using ClamSMTP at students.cs.uu.nl
X-Spam-Checker-Version:
SpamAssassin 3.0.2-hvl (2004-11-16) on dawn.students.cs.uu.nl
X-Spam-Status:
No, score=-0.7 required=7.0 tests=AWL autolearn=ham version=3.0.2-hvl

Hi Keean,
First of all, thank you for your answers. I have tried your solution 
using TypeEq.

instance (Datasource l k' v', TypeEq k k' z, Datasource' z l r k v) =
 Datasource (JoinedDS l r) k v where
 _dsread (JoinedDS refl refr) k = do { l - readIORef refl;
   r - readIORef 
refr; 
   (z,l,r,v) - _dsread' (l,r) k;
   writeIORef refl l;
   writeIORef refr r;
   return (JoinedDS refl refr, v);
 }

class Datasource' z l r k v | l r k - v where
class Datasource' z l r k v | z l r k - v where
 _dsread'  :: (l,r) - k - IO (z,l,r,Maybe v)
 _dswrite' :: (l,r) - k - v - IO (z,l,r)
instance Datasource l k v = Datasource' HTrue  l r k v where
 _dsread' (l,r) k = do { (l,v) - _dsread l k;
 return (hTrue, l, r, v);
   }
instance Datasource r k v = Datasource' HFalse l r k v where
 _dsread' (l,r) k = do { (r,v) - _dsread r k;
 return (hFalse, l, r, v);
   }
This compiles.
I cannot, however, include type z in the fundep of Datasource', since 
this conflicts with Datasource ds k v | ds 

Re: Oops [Fwd: Re: Allowing duplicate instances in GHC 6.4]

2005-03-31 Thread Keean Schupke
Some more fixes...
Keean Schupke wrote:
Hi Keean,
First of all, thank you for your answers. I have tried your solution 
using TypeEq.

instance (Datasource l k' v', TypeEq k k' z, Datasource' z l r k v) =
 Datasource (JoinedDS l r) k v where
 _dsread (JoinedDS refl refr) k = do { l - readIORef refl;
   r - readIORef 
refr; 
   (z,l,r,v) - _dsread' (l,r) k;
   writeIORef refl l;
   writeIORef refr r;
   return (JoinedDS refl refr, v);
 }

   _dsread (JoinedDS l r) k = _dsread' (typeEq (undefined::k') k) l r k
class Datasource' z l r k v | l r k - v where

class Datasource' z l r k v | z l r k - v where
 _dsread'  :: (l,r) - k - IO (z,l,r,Maybe v)
 _dswrite' :: (l,r) - k - v - IO (z,l,r)
instance Datasource l k v = Datasource' HTrue  l r k v where
 _dsread' (l,r) k = do { (l,v) - _dsread l k;
 return (hTrue, l, r, v);

The type says the return type of Datasource' is v where v is the type 
resturned from _dsread so:

  _dsread' _ (l,r) k = _dsread l k
The types are determined by the instance... (I don't understand why you 
are trying to return
hTrue

   _dsread :: s - k - v
and for Datasource'
   _dsread :: z - l - r - k - v
   }
instance Datasource r k v = Datasource' HFalse l r k v where
 _dsread' (l,r) k = do { (r,v) - _dsread r k;
 return (hFalse, l, r, v);
   }
This compiles.
I cannot, however, include type z in the fundep of Datasource', since 
this conflicts with Datasource ds k v | ds k - v. Furthermore, I do 
not understand how the key and value types of my right datasource (r 
k v) is bound to the instance of Datasource (JoinedDS l r) k v, since 
in the premisse (Datasource l k' v', TypeEq k k' z, Datasource' z l r 
k v), nothing is said about Datasource r k'' v''. However, I could be 
wrong in this, since Datasource r k v is in the premisse of instance 
Datasource r k v = Datsource' HFalse l r k v.

However, my problem is, that when I use this code:
do {joined - createJoinedDS' x y;
 (joined,(v::Maybe Int)) - _dsread joined (2.0::Float);
}
{- | Easy constructor -}
createJoinedDS :: (IORef left) - (IORef right) - JoinedDS left right
createJoinedDS left right = JoinedDS left right
createJoinedDS' :: left - right - IO (JoinedDS left right)
createJoinedDS' l r = do { left - newIORef l;
  right - newIORef r;
  return (createJoinedDS left right);
}
the compiler will complain:
 Could not deduce (Datasource' z1 l r k v)
 from the context (Datasource (JoinedDS l r) k v,
   Datasource l k' v',
   TypeEq k k' z,
   Datasource' z l r k v)
 arising from use of `_dsread''
It seems to be the case that it cannot decide on the type of z.
See change above!
Also note type of fundep for Datasource should now be:
class Datasource s k v | s - k v where ...
   Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Oops [Fwd: Re: Allowing duplicate instances in GHC 6.4]

2005-03-31 Thread Keean Schupke
Not at all... You can have Datasource s k v | s k - v ... but I have't 
time to do it now...

By the way that wasn't the change I was talking about!
class Datasource' z l r k v | z l r k - v
The 'z' was missing from your fundep.
   Keean.
Robert van Herk wrote:

See change above!
Also note type of fundep for Datasource should now be:
class Datasource s k v | s - k v where ...

I see But the cool thing was, that my datasources were generic, in 
the sence that they could store multiple k's and v's. Now, they would 
be unique for the actual storage mechanism used, meaning, for example, 
that I could only read values from 1 table, if I'd instantiate the 
datasource for a database coupling.

Currently, I use the Boilerplate approach to make it possible to store 
multiple types in one datasource, for example:

data MyKeyVal = IntXString Int String
| FloatXInt  Float Int
deriving (Eq, Ord, Show)
Furthermore, I generate an instance of KeyHasValue, to tell my 
framework which keys are valid for a datasource, for example:

instance KeyHasValue MyKeyVal Int String where
constructor = IntXString
instance KeyHasValue MyKeyVal Float Int where
constructor = FloatXInt
I have an instance
instance (..., KeyHasValue a k v) =
Datasource [a] k v where ...
This way, I can read Ints from a [MyKeyVal], and get a String, and 
read Floats, and get an Int. If I would have a fundep
class Datasource s k v | s - k v where ...

this wouldn't be possible anymore, I guess?
Regards,
Robert
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Oops [Fwd: Re: Allowing duplicate instances in GHC 6.4]

2005-03-31 Thread Keean Schupke
In the case where a datasource is determined by 's' and 'k', we need to 
return a different
type depending on sucess or failure:

data TJust t = TJust t
data TNothing = TNothing

class Datasource s k v | s k - v where
dsread :: s - k - v
instance (Datasource l k v',Datasource r k v'',Datasource' v' v'' v)
= Datasource (JoinedDS l r) k v where
dsread (JoinedDS l r) k =  dsread' (dsread l k) (dsread r k)

class Datasource' l r v | l r - v where
dsread' :: l - r - v
instance Datasource' TNothing TNothing TNothing where
dsread' _ _ = TNothing
instance Datasource' (TJust l) TNothing (TJust l) where
dsread' t _ = t
instance Datasource' TNothing (TJust r) (TJust r) where
dsread' _ t = t
instance Datasource' (TJust l) (TJust r) TNothing where
dsread' _ _ = TNothing
Now all you need to do is arrange for individual datasources to
return (TJust v) if that combination of source and key exist and
TNothing if they dont. Something like:
instance Datasource Source1 Key1 (TJust Value1)
instance Datasource Source1 Key2 TNothing

instance Datasource Source2 Key1 TNothing
instance Datasource Source2 Key2 (TJust Value2)
This is a simple implementation, using TypeEq, you can generically
reject with TNothing all datasource instances not specifically defined.
   Keean.
Hi Keean,
First of all, thank you for your answers. I have tried your solution 
using TypeEq.

instance (Datasource l k' v', TypeEq k k' z, Datasource' z l r k v) =
 Datasource (JoinedDS l r) k v where
 _dsread (JoinedDS refl refr) k = do { l - readIORef refl;
   r - readIORef 
refr; 
   (z,l,r,v) - _dsread' (l,r) k;
   writeIORef refl l;
   writeIORef refr r;
   return (JoinedDS refl refr, v);
 }

class Datasource' z l r k v | l r k - v where
 _dsread'  :: (l,r) - k - IO (z,l,r,Maybe v)
 _dswrite' :: (l,r) - k - v - IO (z,l,r)
instance Datasource l k v = Datasource' HTrue  l r k v where
 _dsread' (l,r) k = do { (l,v) - _dsread l k;
 return (hTrue, l, r, v);
   }
instance Datasource r k v = Datasource' HFalse l r k v where
 _dsread' (l,r) k = do { (r,v) - _dsread r k;
 return (hFalse, l, r, v);
   }
This compiles.
I cannot, however, include type z in the fundep of Datasource', since 
this conflicts with Datasource ds k v | ds k - v. Furthermore, I do 
not understand how the key and value types of my right datasource (r k 
v) is bound to the instance of Datasource (JoinedDS l r) k v, since in 
the premisse (Datasource l k' v', TypeEq k k' z, Datasource' z l r k 
v), nothing is said about Datasource r k'' v''. However, I could be 
wrong in this, since Datasource r k v is in the premisse of instance 
Datasource r k v = Datsource' HFalse l r k v.

However, my problem is, that when I use this code:
do {joined - createJoinedDS' x y;
 (joined,(v::Maybe Int)) - _dsread joined (2.0::Float);
}
{- | Easy constructor -}
createJoinedDS :: (IORef left) - (IORef right) - JoinedDS left right
createJoinedDS left right = JoinedDS left right
createJoinedDS' :: left - right - IO (JoinedDS left right)
createJoinedDS' l r = do { left - newIORef l;
  right - newIORef r;
  return (createJoinedDS left right);
}
the compiler will complain:
 Could not deduce (Datasource' z1 l r k v)
 from the context (Datasource (JoinedDS l r) k v,
   Datasource l k' v',
   TypeEq k k' z,
   Datasource' z l r k v)
 arising from use of `_dsread''
It seems to be the case that it cannot decide on the type of z.
Would you know how to solve this?
Regards,
Robert
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: moving from ghc-6.2 to 6.4

2005-03-29 Thread Keean Schupke
Thought I would run some benchmarks with different compiler options, so 
I pulled out some code (that compiled fine with 6.2). The code uses 
MArrays to calculate a tree difference between two different XML files. 
Anyway tying to compile with 6.4 I get:

ghc-6.3: panic! (the `impossible' happened, GHC version 6.3):
app_match: unbound tpl s{tv a2M9}

Please report it as a compiler bug to glasgow-haskell-bugs@haskell.org,
Any idea how to track down the cause of this?
   Keean.
Simon Marlow wrote:
On 29 March 2005 08:59, Johannes Waldmann wrote:
 

I am trying to bring a larger heap of code
(http://141.57.11.163/auto/ ) into 6.4 land (because of wonder
stories about faster compilation, faster execution, Data.Map, and so
on ...) 
Here are a few observations and questions
that may be useful to others as well.

* what is the situation with ghc-6.4 for sparc/solaris?
  I don't see a binary package in the download area.
  I started to build from source - can this be successful?
  (The rest of this report refers to i386/linux)
   

There are some outstanding issues on Sparc/Solaris that I didn't get
around to investigating before the release.  One of them is a random
crash, so you should probably consider 6.4 to be broken on Sparc/Solaris
for the time being (it might be related to gcc version though: 6.2.x
might be just as broken with recent gcc versions).  I'm keen to get more
data points, if you have the time  inclination to test it.
We could really do with a Sparc/GHC guru to take up the mantle of
maintaining the Sparc port - it's kind of hard for us to do it without
the hardware locally, and I'm no Sparc expert.
 

* Cabal is very nice! - The only thing that was confusing me
  is that I have to list all modules in the *.cabal file:
  if I don't, it still happily builds and installs the package
  but it cannot be used, giving linker errors. Couldn't this be
  checked earlier? Or better, couldn't it infer the needed
  hidden modules? Anyway I can generate the module list by a shell
  script but that does not feel right. - How do I build and install
  a profiling version of a package, how does Cabal support this?
   

The module list: yes, I think this is something the Cabal team would
like to automate in the future.  There's no way to build profiled
packages at the moment, as far as I'm aware.  I agree it's an important
feature, though.
 

* I don't see dramatic improvements in execution times -
  are there some magic ghc options I missed? I used -O -fvia-C.
  Still, executables are maybe 2 .. 5 % smaller and faster than they
  were with 6.2 - and compilation without -O is really fast.
   

I don't know where this rumour of dramatic improvements in execution
time comes from :-)  Our testing shows modest improvements in most
programs, with some programs going slower.  The focus of 6.4 wasn't
really on performance, but we hope to merge performance improvements
back into future 6.4 releases.
Cheers,
	Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
 

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Allowing duplicate instances in GHC 6.4

2005-03-25 Thread Keean Schupke
Robert van Herk wrote:
Hi all,
I need to use duplicate instances. I read in the documentation on GHC 
6.4, that overlapping class instances checks are lazy instead of 
gready in 6.4. However, my code still gives duplicate instance errors 
when compiling in GHC 6.4.

Is the duplicate instance check still gready? Is there a way to 
overwrite that behaviour?

Right now, I have two instance of a class Datasource. Datasource 
allows the user to read (key,value) pairs.

class Datasource ds k v where
...
Now, I wanted to make a special datasource that combines two 
datasources, namely

data JoinedDS left right = JoinedDS left right
instance (Datasource left k v) = Datasource (JoinedDS left right) k v 
where
...

instance (Datasource right k v) = Datasource (JoinedDS left right) k 
v where
...

The idea is that when you combine 2 datasources in one JoinedDS, the 
user can read both types from the JoinedDS. I do not need to allow to 
combine 2 different datasources that have the same types of 
(key,value) pairs, so the duplicate instances will not occur and when 
they do, this will be by mistake. Hence, the two premisses in the 
instance declaration will never be fulfilled both at the same time and 
I do not want a duplicate instance error here.

Is there a  solution to this problem?
To resolve overlap the HEAD of the instance must be different... Might I 
suggest:

-- as value depends on source and key, requires functional dependancy
class Datasource s k v | s k - v ...
data JoinedDS l r = JoinedDS l r
instance (Datasource l k v1,Datasource r k v2) = Datasource (JoinedDS l 
r) k (v1,v2) ...

Now a joined datasource resturns a pair of values instead of a single value.
   Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Allowing duplicate instances in GHC 6.4

2005-03-25 Thread Keean Schupke
Keean Schupke wrote:
Robert van Herk wrote:
Hi all,
I need to use duplicate instances. I read in the documentation on GHC 
6.4, that overlapping class instances checks are lazy instead of 
gready in 6.4. However, my code still gives duplicate instance errors 
when compiling in GHC 6.4.

Is the duplicate instance check still gready? Is there a way to 
overwrite that behaviour?

Right now, I have two instance of a class Datasource. Datasource 
allows the user to read (key,value) pairs.

class Datasource ds k v where
...
Now, I wanted to make a special datasource that combines two 
datasources, namely

data JoinedDS left right = JoinedDS left right
instance (Datasource left k v) = Datasource (JoinedDS left right) k 
v where
...

instance (Datasource right k v) = Datasource (JoinedDS left right) k 
v where
...

The idea is that when you combine 2 datasources in one JoinedDS, the 
user can read both types from the JoinedDS. I do not need to allow to 
combine 2 different datasources that have the same types of 
(key,value) pairs, so the duplicate instances will not occur and when 
they do, this will be by mistake. Hence, the two premisses in the 
instance declaration will never be fulfilled both at the same time 
and I do not want a duplicate instance error here.

Is there a  solution to this problem?
To resolve overlap the HEAD of the instance must be different... Might 
I suggest:

-- as value depends on source and key, requires functional dependancy
class Datasource s k v | s k - v ...
data JoinedDS l r = JoinedDS l r
instance (Datasource l k v1,Datasource r k v2) = Datasource (JoinedDS 
l r) k (v1,v2) ...

Now a joined datasource resturns a pair of values instead of a single 
value.

 
Further to this to get the exact behaviour you want, if a datasource can 
return the result using a type lifted maybe on a lookup failure then:

class Datasource s k v | s k - v ...
data JoinedDS l r = JoinedDS l r
instance (Datasource l k v1,
Datasource r k v2,
JoinDS v1 v2 v) = Datasource (JoinedDS l r) k v

class Fail
data This_should_never_happen

data TNothing = TNothing
data TJust a = TJust a

class JoinDS l r t | l r - t
instance JoinDS TNothing TNothing TNothing
instance JoinDS TNothing (TJust v) (TJust v)
instance JoinDS (TJust u) TNothing (TJust u)
instance Fail This_should_never_happen = JoinDS (TJust u) (TJust v) 
TNothing

Now you datasources just need to return the type TJust v on success 
and TNothing on failure.

   Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Allowing duplicate instances in GHC 6.4

2005-03-25 Thread Keean Schupke
There was a typo in the code I posted:

class Fail
data This_should_never_happen

should read:

class Fail x
data This_should_never_happen

Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Allowing duplicate instances in GHC 6.4

2005-03-25 Thread Keean Schupke
Just thought I ought to point out that all this is only necessary if the 
datasources may return different types... If you want them to return the 
same type you only need:

instance (Datasource l k v,Datasource r k v) = Datasource (JoinedDS l 
r) k v ...

As both datasources have the same key and value types, you then choose 
which 'v' to return at the value level.

I am not sure whether you intended Datasources to contain heterogeneous 
key or value types, and whether the loolup is supposed to be value or 
type driven. My original answer assumed a single Datasource contains 
values of different types, selected by the type of the key...

   Keean.

Robert van Herk wrote:
Yes, but this is not what I want. I want to be able to give a key that 
either the left or the right data source would take, and then return 
the appropriate value. Thus: if I pass it a key that would normally go 
into l, I want the value l returns me to be returned, and if I pass it 
the key that would normally go into r, I want to return the value r 
returns me.

The datasource class has a function dsread :: ds - k - (ds, v) -- 
read may have a side effect
Thus I want want to do something like:
instance (Datasource l k v) = Datasource (JoinedDS l r) k v where
 dsread (JoinedDS l r) k = let (l, v) = dsread l k in (JoinedDS l r, v)
instance (Datasource r k v) = Datasource (JoinedDS l r) k v where
 dsread (JoinedDS l r) k = let (r, v) = dsread r k in (JoinedDS l r, v)

It would be perfectly okay to me when the compiler would complain if 
the key and value that go into l and r are the same, but for any 
useful purpose I can think of (e.g. glueing two database couplings 
together, since I also made a Datasource instance for database 
access), this will not happen and the duplicate instances should not 
really occur, since the context of the instances makes sure only 1 
will be possible.

However, GHC only looks at the RHS (thus: Datasource (JoinedDS l r) k 
v) and then decides that both instances are the same.

So, my question was: how to overcome this.
Thanks,
Robert

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Allowing duplicate instances in GHC 6.4

2005-03-25 Thread Keean Schupke
Robert van Herk wrote:
Keean Schupke wrote:
Just thought I ought to point out that all this is only necessary if 
the datasources may return different types... If you want them to 
return the same type you only need:

instance (Datasource l k v,Datasource r k v) = Datasource (JoinedDS 
l r) k v ...

As both datasources have the same key and value types, you then 
choose which 'v' to return at the value level.

Nono, the datasources I have implemented are a type safe means to 
extract (key,value) pairs from a data store. The idea is that this 
way, in a type safe fashion, e.g. database access can be abstract.

I use HaskellDB as the database access layer, and then define a 
datasource instance for any given database, so that the user does not 
need to think about the details of the actual database access: he can 
just read and write from the datasource, and the datasource will make 
sure the actual queries will be executed.

My idea now was that if I have 2 databases, and I construct 
datasources for them, it would be really cool if I was able to unite 
them, so that the programmer in the end could talk two 1 datasource, 
that allowed for accessing the 2 databases at one entry point. This 
was what I was making the JoinedDS for.

So, suppose I have 2 datasources for two different databases. One may 
have keys:
data KeysOfDS1 = KDB1_Table1 Int
   |  KDB1_Table2 Int

and values
data ValuesOfDS1 = VDB1_Table1 (Int,Int,String)
   | VDB2_Table2 (Int,Int,String)
and the other one:
data KeysOfDS2 = KDB2_Table1 String
   |  KDB2_Table2 String
data ValuesOfDS2 = VDB2_Table1 (String, Float)
   | VDB2_Table2 (String, Float, Int)
Now, these datastructures correspond to the actual tables in the 
database. My toolset will generate datasources for these types, thus 
we have instances:

instance Datasource Database1 KeysOfDS1 ValuesOfDS1
instance Datasource Database2 KeysOfDS2 ValuesOfDS2
and the cool thing would be, to combine these two datasources at a 
higher level in my datasources graph, so that I would have 1 
datasource that found out by itself which actual datasource to use, thus:

x::JoinedDS
x = JoinedDS  db1 db2 -- where dbx is a datasource Databasex KeysOfDSx 
ValuesOfDSx

Now, I would want the user to be able to read both KeysOfDS1 (which 
would yield a ValuesOfDS1) as well as KeysOfDS2 (which would yield a 
ValuesOfDS2) from x.

Herefore, I need the instances mentioned before:
instance (Datasource l k v) = Datasource (JoinedDS l r) k v where
dsread (JoinedDS l r) k = let (l, v) = dsread l k in (JoinedDS l r, v)
instance (Datasource r k v) = Datasource (JoinedDS l r) k v where
dsread (JoinedDS l r) k = let (r, v) = dsread r k in (JoinedDS l r, v)
But this, thus, yields duplicate instance errors, which I don't like :-).
Robert
P.S. Sorry for any typos, I am enjoying a rather nice bottle of wine :-).
Thats because they overlap in 'k'. However you can change the fundep:
class Datasource s k v | s - k v
instance Datasource DB1 K1 V1
instance Datasource DB2 K2 V2
instance (Datasource l k' v',TypeEq k k' z,Datasource' z l r k v) = 
Datasource (JoinedDS l r) k v where

class Datasource' z l r k v | z l r - k v
instance Datasource l k v = Datasource' TTrue l r k v
instance Datasource r k v = Datasource' TFalse l r k v

Here I have used TypeEq from the HList library to determine if the type 
parameter k is the same type as the k' from datasource l. This lets k 
determine which instance from the other class gets used.

   Keean.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell] Haskell 6.4 perfomance

2005-03-24 Thread Keean Schupke
Think this should really go to glasgow-haskell-users...
If this is true - how do I get ghc to use C--, and is it really faster 
than using gcc as a backend with all the bells  whistles turned on (for 
a pentium-III) something like

   -O3 -mcpu=pentium3 -march=pentium3 -pipe -fomit-frame-pointer 
-momit-leaf-frame-pointer -ftracer -fno-crossjumping -mfpmath=sse,387 
-ffast-math -fsched-spec-load -fprefetch-loop-arrays 
-maccumulate-outgoing-args -fmove-all-movables
-freduce-all-givs

   Keean.
Alexandre wrote:
As I heard, 6.4 version of the Haskell using C-- backend and make lots 
of the resulting code perfomance (programs executed faster).
If so, does any test/comparison with other languages available?

Thank you in advance,
Regards,
/Alexandre.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell] The FunctorM library

2005-03-24 Thread Keean Schupke
Why not just have the new definition with a different import path, so 
that legacy code continues to do:

import Control.Monad
And new code could do:
import Control.Category.Monad (or something)
And we could take this opportunity to incorporate premonads...
class Functor f -- defines fmap
class Functor p = Premonad p -- defines return
class Premonad m = Monad m -- defines bind
   Keean.
Simon Peyton-Jones wrote:
|  Yes, I think this should be fixed, and perhaps it could be done in a
|  backward compatible way? If classes were allowed to declare default
|  methods for superclasses, then you could have
| 
|  class Functor f where fmap :: ...
|  class Functor m = Monad m where
| ...the usual stuff...
| fmap = liftM
| 
|  Then declaring
| 
|  instance Monad T where ...
| 
|  for some T, would implicitly introduce an instance Functor T, if it
is
|  not defined explicitly...
It seems overkill to have a whole new language feature to deal with one
library issue.  It would take a bit of implementing too, and it's not
clear to me what the specification is.  For example, what if Functor T
*is* defined explicitly, but in a later module?
The idea comes up very occasionally, but I wouldn't say it's been a hot
issue.
Simon
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
 

___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Haskell 6.4 perfomance

2005-03-24 Thread Keean Schupke
Think this should really go to glasgow-haskell-users...
If this is true - how do I get ghc to use C--, and is it really faster 
than using gcc as a backend with all the bells  whistles turned on (for 
a pentium-III) something like

   -O3 -mcpu=pentium3 -march=pentium3 -pipe -fomit-frame-pointer 
-momit-leaf-frame-pointer -ftracer -fno-crossjumping -mfpmath=sse,387 
-ffast-math -fsched-spec-load -fprefetch-loop-arrays 
-maccumulate-outgoing-args -fmove-all-movables
-freduce-all-givs

   Keean.
Alexandre wrote:
As I heard, 6.4 version of the Haskell using C-- backend and make lots 
of the resulting code perfomance (programs executed faster).
If so, does any test/comparison with other languages available?

Thank you in advance,
Regards,
/Alexandre.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] Linux device drivers

2005-03-22 Thread Keean Schupke
Actually with PCI chipsets, implementing a generic BusMaster DMA driver
is not too hard, assuming you already have interrupts handled (and you 
don't want 64bit DMA support)... You just load the parameters for the 
disk read into the PCI registers, and wait for the completed interrupt. 
I wrote a diver in assembly language for my own OS project a few years ago.

   Keean.
Iavor Diatchki wrote:
Hello,
There are no storage drivers at the moment.  Actually part of the
motivation for implementing the networking stuff was so that we can
avoid doing that at least for the time being.
-Iavor
On Mon, 21 Mar 2005 01:32:19 -0500 (Eastern Standard Time), S.
Alexander Jacobson [EMAIL PROTECTED] wrote:
 

Very very cool.
Has anyone written any storage drivers?
If there is already TCP, has someone written an iscsi (RFC3720)
driver?
-Alex-
On Mon, 21 Mar 2005, Donald Bruce Stewart wrote:
   

dons:
 

alex:
   

Wow!  Did you also implement tcp in Haskell?
 

On this topic, the following House code looks relevant:
  http://cvs.haskell.org/cgi-bin/cvsweb.cgi/programatica/hOp/kernel/Net/
There's something satsifying about seeing 'instance Functor Packet' in
IPv4.hs ;)
 

Does hOp or House also have the ability to write to disk?
(With HAppS, I've gotten rid of the AMP part of LAMP, it would be
really cool to get rid of the L as well!)
 

Sorry! By We've got a few drivers written in Haskell, I meant
the Haskell community, not me personally :} You have the hOp and House
developers to thank for this stuff.
   

On Mon, 21 Mar 2005, Donald Bruce Stewart wrote:
 

mark:
   

I was wondering about the possibility of using Haskell for developing
device drivers that would be kernel modules for Linux. If nothing else,
it would be quite an educational experience for me, as I've not yet
experimented with either the Linux kernel or Haskell FFI, nor have I
had to learn how to squeeze much performance out of my Haskell code.
Clearly, this application demands special things from the compiler and
the runtime. But, I'm not exactly sure what, nor how to achieve such
given current compilers. Does anyone have any thoughts?
 

Well, it would be tricky, but fun!
We've got a few drivers written in Haskell already (but not for Linux,
as far as I know). For example check out the House network stack and
drivers:
 http://cvs.haskell.org/cgi-bin/cvsweb.cgi/programatica/hOp/
and
 
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/programatica/hOp/kernel/Kernel/Driver/NE2000/
So there's heavy use of Data.Bits and Word# types - but nothing that
isn't fairly well established in GHC Haskell, anyway.
Then (for GHC, anyway) you'd have to link the kernel against libHSrts.a,
much
as we do when calling Haskell from other kinds of C apps, which involves
compiling the C app with all the magic flags ghc normally sets up (ghc -v9
main.c is helpful).  Something like: ;)
egcc -v -o a.out -DDONT_WANT_WIN32_DLL_SUPPORT main.o
-L/home/dons/lib/ghc-6.4 -lHStemplate-haskell -lHSCabal -lHSposix
-lHSposix_cbits -lHSlang -lHSmtl -lHShaskell-src -lHSunix -lHSunix_cbits
-lHShi -lHShaskell98 -lHSaltdata -lHSbase -lHSbase_cbits -lHSrts -lm -lgmp
-u GHCziBase_Izh_static_info -u GHCziBase_Czh_static_info -u
GHCziFloat_Fzh_static_info ...
Then, having the kernel start up the Haskell rts (at boot would be
good):
   hs_init(argc, argv);
 .. do something in Haskell or C land ...
   hs_exit();
Then you'd could dyn load (via GHC's rts) your Haskell driver into the C
app, and use it, as long as you've got a nice ffi interface to pass
values back and forward.
I'm sure the fun part is in the details ;)
Cheers,
Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
   

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
   

__
S. Alexander Jacobson tel:917-770-6565 http://alexjacobson.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
   

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linux device drivers

2005-03-22 Thread Keean Schupke
I thought the BusMaster interface was pretty uniform, unlike the earlier 
DMA interfaces which varied from chipset to chipset.

   Keean.
Lennart Augustsson wrote:
But there are plenty of minor variations on how to program
and initiate DMA for different devices.
-- Lennart
Keean Schupke wrote:
Actually with PCI chipsets, implementing a generic BusMaster DMA driver
is not too hard, assuming you already have interrupts handled (and 
you don't want 64bit DMA support)... You just load the parameters for 
the disk read into the PCI registers, and wait for the completed 
interrupt. I wrote a diver in assembly language for my own OS project 
a few years ago.

   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] tuple and HList

2005-03-22 Thread Keean Schupke
Oleg has just pointed out that the 'Show' constraint bellow does not 
work if you try and use a function from the show class (say 'show'), as 
the function:

test2 l = show l
has the type:
test2 :: forall a. (Show a) = a - String
The technique below works to constrain for membership of a class, So we 
know all
elements in the list are instances of show, but we cannot call functions.

The best thing here is to let the compiler infer any remaining 
constraints using:

showList :: ConstrainedList SHOW l = l - String
showList = undefined
test l
   | False = showList l
   | otherwise = show (hHead l)
Here the 'False' guard is never executed, but its type is unified with 
the inferred type for 'show l'... ghci shows us:

*Main :type test
test :: forall b a.
   (Show a, ConstrainedList SHOW (HCons a b)) =
   HCons a b - String
In other words use constraints only to enforce explicit requirements, 
the compiler can safely infer all required constraints from the code (IE 
just don't give signatures for the functions).

Keean.

Keean Schupke wrote:
You can avoid the need to declare a new class for each constrained list
by using the following:
class Constraint c a

data SHOW
instance Show a = Constraint SHOW a

class HListConstraint c l
instance HListConstraint c HNil
instance (Constraint c a,HListConstraint c l) = HListConstraint c 
(HCons a l)

You can now constrain a list as follows:
assertShow :: HListConstraint SHOW l = l - l
assertShow = id
The type parameter can be made first class using:
showConstraint :: SHOW
showConstraint = undefined
So we can now pass this as a parameter:
assertConstraintOnHList :: HListConstraint c l = c - l - l
assertConstraintOnHList _ = id
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linux device drivers

2005-03-22 Thread Keean Schupke
Have a look at the linux kernel IDE drivers, look for
Generic IDE Chipset support
Generic PCI bus-master DMA support
   Keean.
Lennart Augustsson wrote:
What is this standard BusMaster interface you talk about?
I must have missed something.  I've yet to see two PCI chips
that do DMA the same way.
-- Lennart
Keean Schupke wrote:
I thought the BusMaster interface was pretty uniform, unlike the 
earlier DMA interfaces which varied from chipset to chipset.

   Keean.
Lennart Augustsson wrote:
But there are plenty of minor variations on how to program
and initiate DMA for different devices.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linux device drivers

2005-03-22 Thread Keean Schupke
The generic busmaster diver should go all the way to UDMA mode 4 (133Mb)
   Keean.
Lennart Augustsson wrote:
Keean Schupke wrote:
Have a look at the linux kernel IDE drivers, look for
Generic IDE Chipset support
That's the part I missed, you were talking about IDE
chips.  Yes, they have many similarities.  You can
probably run many of them in one of the slower modes
with a common driver.  But even these chips differ
in the details.
-- Lennart

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Linux device drivers

2005-03-22 Thread Keean Schupke
I don't think I said anything controversial. I guess I was just 
over-simplifying things by only considering PC IDE hardware - but then 
again that must get you running on 90% of the systems people are likely 
to have lying around to play with a developmental OS on.

On the other hand the average network driver seems to be about 2,000 
lines of code, whereas if you add all the parts of the generic ide 
driver together you get about 20,000 lines of code. I guess that answers 
my question - storage is an order of magnitude harder than networking, 
even before including SCSI.

   Regards,
   Keean.

Simon Marlow wrote:
Keean, you should be aware that Lennart is something of a device driver
guru.  He knows what he's talking about :-)  Go grep for Augustsson in
the NetBSD kernel sometime.
Cheers,
	Simon
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] tuple and HList

2005-03-21 Thread Keean Schupke
David Menendez wrote:
   instance Functor ((,) a) where
   fmap f (x,y) = (x, f y)
 


If we get rid of '(,)' and redefine '(a,b)' as sugar for 'TCons a (TCons
b HNil)' (or whatever), then there is no way to declare the above instance. I don't think that's a deal-killer, but it is a disadvantage.
 

You need to swap the arguments to TCons...
data TCons l a = TCons !l a
Then:
instance Functor (TCons (TCons HNil a)) where
   fmap f (TCons (TCons HNil x) y) = TCons (TCons HNil (f x)) y)
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] invalid character encoding

2005-03-20 Thread Keean Schupke
One thing I don't like about this automatic conversion is that it is 
hidden magic - and could catch people out. Let's say I don't want to use 
it... How can I do the following
(ie what are the new API calls):

   Open a file with a name that is invalid in the current locale (say a 
zip disc from a computer with a different locale setting).

   Open a file with contents in an unknown encoding.
   What are the new binary API calls for file IO?
   What type is returned from 'getChar' on a binary file. Should it 
even be called getChar? what about getWord8 (getWord16, getWord32 etc...)

   Does the encoding translation occur just on the filename or the 
contents as well? What if I have an encoded filename with binary 
contents and vice-versa.

   Keean.
(I guess I now have to rewrite a lot of file IO code!)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] tuple and HList

2005-03-20 Thread Keean Schupke
Frederik Eaton wrote:
Another thing which I don't think is mentioned in the paper, which is
convenient, is that you can define HLists all of whose elements are
members of a given class:
class HListShow l
instance HListShow HNil
instance (Show a, HListShow l) = HListShow (a :* l)
 

You can avoid the need to declare a new class for each constrained list
by using the following:
class Constraint c a

data SHOW
instance Show a = Constraint SHOW a

class HListConstraint c l
instance HListConstraint c HNil
instance (Constraint c a,HListConstraint c l) = HListConstraint c 
(HCons a l)

You can now constrain a list as follows:
assertShow :: HListConstraint SHOW l = l - l
assertShow = id
The type parameter can be made first class using:
showConstraint :: SHOW
showConstraint = undefined
So we can now pass this as a parameter:
assertConstraintOnHList :: HListConstraint c l = c - l - l
assertConstraintOnHList _ = id
   Keean.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] tuple and HList

2005-03-20 Thread Keean Schupke
Frederik Eaton wrote:
That's a neat technique. Since it's so general it would be nice if
there were a way to make it more automatic, could one use template
haskell? It seems one should be able to write
HListConstraint $(mkConstraint Show) l
to generate the declarations automatically.
Frederik
 

This is planned as part of a template-haskell library  allowing automatic
lifting of data types to classes.
This would most likely be written:
$(ttypelift [d|
   type ShowList = [Show] |])
or for a function
$(ttypelift [d|
   f :: [Show] - [Show]
|]
(Here Show is assumed to be defined as a type in the environment)
Lifting a list of type [Show] produces an HList where each element is
constrained to be an instance of the class Show.
If we consider type level naturals we can define a list [HNat] where
each element is a type level natural number.
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] invalid character encoding

2005-03-19 Thread Keean Schupke
David Roundy wrote:
That's not true, there could be many filesystems, each of which uses a
different encoding for the filenames.  In the case of removable media, this
scenario isn't even unlikely.
 

I agree - I can quite easily see the situation occuring where a student 
(say from japan) brings in a zip-disk or USB key formatted with a 
japanese filename encoding, that I need to read on my computer (with a 
UK locale).

Also can different windows have different encodings? I might have a web 
browser (written in haskell?) running and have windows with several 
different encodings open at the same time, whist saving things on 
filesystems with differing encodings.

Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] invalid character encoding

2005-03-17 Thread Keean Schupke
I cannot help feeling that all this multi-language support is a mess.
All strings should be coded in a universal encoding (like UTF8) so that 
the code for a character is the same independant of locale.

It seems stupid that the locale affects the character encodings... the 
code for an 'a' should be the same all over the world... as should the 
code for a particular japanese character.

In other words the locale should have no affect on character encodings, 
it should select between multi-lingual error messages which are supplied 
as distinct strings for each region.

While we may have to inter-operate with 'C' code, we could have a 
Haskell library that does things properly.

   Keean.
Marcin 'Qrczak' Kowalczyk wrote:
Glynn Clements [EMAIL PROTECTED] writes:
 

The (non-wchar) curses API functions take byte strings (char*),
so the Haskell bindings should take CString or [Word8] arguments.
   

Programmers will not want to use such interface. When they want to
display a string, it will be in Haskell String type.
And it prevents having a single Haskell interface which uses either
the narrow or wide version of curses interface, depending on what is
available.
 

If you provide wrapper functions which take String arguments,
either they should have an encoding argument or the encoding should
be a mutable per-terminal setting.
   

There is already a mutable setting. It's called locale.
 

I don't know enough about the wchar version of curses to comment on
that.
   

It uses wcsrtombs or eqiuvalents to display characters. And the
reverse to interpret keystrokes.
 

It is possible for curses to be used with a terminal which doesn't
use the locale's encoding.
   

No, it will break under the new wide character curses API, and it will
confuse programs which use the old narrow character API.
The user (or the administrator) is responsible for matching the locale
encoding with the terminal encoding.
 

Also, it's quite common to use non-standard encodings with terminals
(e.g. codepage 437, which has graphic characters beyond the ACS_* set
which terminfo understands).
   

curses don't support that.
 

The locale encoding is the right encoding to use for conversion of the
result of strerror, gai_strerror, msg member of gzip compressor state
etc. When an I/O error occurs and the error code is translated to a
Haskell exception and then shown to the user, why would the application
need to specify the encoding and how?
 

Because the application may be using multiple locales/encodings.
   

But strerror always returns messages in the locale encoding.
Just like Gtk+2 always accepts texts in UTF-8.
For compatibility the default locale is C, but new programs
which are prepared for I18N should do setlocale(LC_CTYPE, )
and setlocale(LC_MESSAGES, ).
There are places where the encoding is settable independently,
or stored explicitly. For them Haskell should have withCString /
peekCString / etc. with an explicit encoding. And there are
places which use the locale encoding instead of having a separate
switch.
 

[The most common example is printf(%f). You need to use the C
locale (decimal point) for machine-readable text but the user's
locale (locale-specific decimal separator) for human-readable text.
   

This is a different thing, and it is what IMHO C did wrong.
 

This isn't directly related to encodings per se, but a good example
of why parameters are preferable to state.]
   

The LC_* environment variables are the parameters for the encoding.
There is no other convention to pass the encoding to be used for
textual output to stdout for example.
 

C libraries which use the locale do so as a last resort.
   

No, they do it by default.
 

The only reason that the C locale mechanism isn't a major nuisance
is that you can largely ignore it altogether.
   

Then how would a Haskell program know what encoding to use for stdout
messages? How would it know how to interpret filenames for graphical
display?
Do you want to invent a separate mechanism for communicating that, so
that an administrator has to set up a dozen of environment variables
and teach each program separately about the encoding it should assume
by default? We had this mess 10 years ago, and parts of it are still
alive until today - you must sometimes configure xterm or Emacs
separately, but it's being more common that programs know to use the
system-supplied setting and don't have to be configured separately.
 

Code which requires real I18N can use other mechanisms, and code
which doesn't require any I18N can just pass byte strings around and
leave encoding issues to code which actually has enough context to
handle them correctly.
   

Haskell can't just pass byte strings around without turning the
Unicode support into a joke (which it is now).
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Best practices for modular programming in Haskell

2005-03-17 Thread Keean Schupke
Yes. Its actually very easy once you get how instance resolution
occurs and how constraints work.
I have used this style to code a database interface, and am using the
OOHaskell style (which is related to this kind of stuff) for an application
server (was a SOAP server, but might migrate to the new WebServices
standards).
Infact there is only one real limitation, and that is you cannot
(easily) lift an arbitrary IO value to a type. (You can do this but there
must be a limit to the value).
This does seem solvable however - but not with the current ghc/hugs 
architecture.
To lift a value to a type the code depending on that type cannot be 
compiled/type-checked until the value is known. This would be ideally 
suited to
a JIT compiler.

   Keean.
Benjamin Pierce wrote:
Actually Haskell fully matches the module system of OCaml -- and then
adds some. Haskell provides both generative and applicative (recursive)
functors. The following two messages elucidate the correspondence
http://www.haskell.org/pipermail/haskell/2004-August/014463.html
http://www.haskell.org/pipermail/haskell/2004-September/014515.html
   

Wow.
Do people actually develop significant bodies of code in this style?
  - Benjamin
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Joy Combinators (Occurs check: infinite type)

2005-03-11 Thread Keean Schupke
Greg Buchholz wrote:
   Wow.  Color me impressed.  A little under a week ago, I stumbled
onto Joy, and thought to myself that it could be translated almost
directly into Haskell (which would imply it was possible to statically
type).  Well, it wasn't quite as direct as I had initially thought, but
it looks like you've done it.  Are there any papers/books out there
which I could study to learn more about these (and other) tricks of the
type system wizards? 
 

Here's a cleaned up version, I have made the function composition and 
stack both
use HLists... a bit neater. Have also added primrec and a 5th factorial.

As for type tricks most of these should be in the HList or OOHaskell 
papers. The things to notice are using types as instance labels, that 
constraints form horn
clause compile time meta-programs (in a non-backtracking prolog style) 
and that multi-parameter classes with functional depandencies simulate 
some dependant
types.

   Keean.
{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-overlapping-instances #-}
{-# OPTIONS -fallow-undecidable-instances #-}

--Joy implemented in Haskell... extensible embedded language...

module Joy where

import MainGhcGeneric1

-- Building non-empty lists

type HOne = HSucc HZero
hOne :: HOne
hOne = undefined
type HTwo = HSucc HOne
hTwo :: HTwo
hTwo = undefined
type HThree = HSucc HTwo
hThree :: HThree
hThree = undefined

end :: HNil
end = hNil

instance HList s = Apply HNil s s where
	apply _ s = s
instance (HList s,HList s',HList l,Apply a s s',Apply l s' s'') = Apply (HCons a l) s s'' where
	apply (HCons a l) s = apply l (apply a s :: s')
instance HList s = Apply HZero s (HCons HZero s) where
	apply _ s = hCons hZero s
instance (HNat a,HList s) = Apply (HSucc a) s (HCons (HSucc a) s) where
	apply a s = hCons a s

data Lit a = Lit a
lit :: a - Lit a
lit a = Lit a
unl :: Lit a - a
unl (Lit a) = a
instance Show a = Show (Lit a) where
	showsPrec _ (Lit a) = showChar '[' . shows a . showChar ']'
instance HList s = Apply (Lit a) s (HCons a s) where
	apply (Lit a) s = hCons a s

class (HBool b,HList s) = HIfte b t f s s' | b t f s - s' where
	hIfte :: b - t - f - s - s'
instance (HList s,Apply t s s') = HIfte HTrue t f s s' where
	hIfte _ t _ s = apply t s
instance (HList s,Apply f s s') = HIfte HFalse t f s s' where
	hIfte _ _ f s = apply f s

data Ifte
ifte :: Ifte
ifte = undefined
instance Show Ifte where
	showsPrec _ _ = showString If
instance (Apply b s r,HHead r b',HIfte b' t f s s')
	= Apply Ifte (f :*: t :*: b :*: s) s' where
	apply _ (HCons f (HCons t (HCons b s))) = hIfte (hHead (apply b s :: r) :: b') t f s

data Nul
nul :: Nul
nul = undefined
instance Show Nul where
	showsPrec _ _ = showString Nul
instance HList s = Apply Nul (HCons HZero s) (HCons HTrue s) where
	apply _ (HCons _ s) = hCons hTrue s
instance HList s = Apply Nul (HCons (HSucc n) s) (HCons HFalse s) where
	apply _ (HCons _ s) = hCons hFalse s

data EQ
eq :: EQ
eq = undefined
instance Show EQ where
	showsPrec _ _ = showString Eq
instance (HList s,TypeEq a b t) = Apply EQ (HCons a (HCons b s)) (HCons t s) where
	apply _ (HCons a (HCons b s)) = hCons (typeEq a b) s

data Dip
dip :: Dip
dip = undefined
instance Show Dip where
	showsPrec _ _ = showString Dip
instance (HList s,HList s',Apply a s s') = Apply Dip (HCons a (HCons b s)) (HCons b s') where
	apply _ (HCons a (HCons b s)) = hCons b (apply a s)

data Dup 
dup :: Dup
dup = undefined
instance Show Dup where
	showsPrec _ _ = showString Dup
instance HList s = Apply Dup (HCons a s) (HCons a (HCons a s)) where
	apply _ s@(HCons a _) = hCons a s

data Pop
pop :: Pop
pop = undefined
instance Show Pop where
	showsPrec _ _ = showString Pop
instance HList s = Apply Pop (HCons a s) s where
	apply _ (HCons _ s) = s

data Swap
swap :: Swap
swap = undefined
instance Show Swap where
	showsPrec _ _ = showString Swap
instance HList s = Apply Swap (HCons a (HCons b s)) (HCons b (HCons a s)) where
	apply _ (HCons a (HCons b s)) = hCons b (hCons a s)

data Suc
suc :: Suc
suc = undefined
instance Show Suc where
	showsPrec _ _ = showString Suc
instance (HNat a,HList s) = Apply Suc (HCons a s) (HCons (HSucc a) s) where
	apply _ (HCons _ s) = hCons (undefined::HSucc a) s

data Pre
pre :: Pre
pre = undefined
instance Show Pre where
	showsPrec _ _ = showString Pre
instance (HNat a,HList s) = Apply Pre (HCons (HSucc a) s) (HCons a s) where
	apply _ (HCons _ s) = hCons (undefined::a) s

data Add
add :: Add
add = undefined
instance Show Add where
	showsPrec _ _ = showString Add
instance (HList s,HAdd a b c) = Apply Add (HCons a (HCons b s)) (HCons c s) where
	apply _ (HCons _ (HCons _ s)) = hCons (hAdd (undefined::a) (undefined::b)) s

class (HNat a,HNat b) = HAdd a b c | a b - c where
	hAdd :: a - b - c
instance HAdd HZero HZero HZero where
	hAdd _ _ = hZero
instance HNat b = HAdd HZero (HSucc b) (HSucc b) where
	hAdd _ b = b
instance HNat a = HAdd (HSucc a) HZero (HSucc a) where
	hAdd a _ = a
instance (HNat (HSucc a),HNat (HSucc b),HNat c,HAdd a b c)
	= HAdd 

Re: [Haskell-cafe] Joy Combinators (Occurs check: infinite type)

2005-03-09 Thread Keean Schupke
Greg Buchholz wrote:
Keean Schupke wrote:
 

I dont see why this is illegal... what do we want? take the top two 
items from the stack?
   

   With the code below (direct translation from tuples to HLists) I
still get an occurs check error when trying to define fact5...
 

Okay the reason is that types in the code end up depending on values. The
type of the stack changes when items are pushed or popped. So the type 
of the stack returned from recursive functions depends on the recursion 
count...

Haskell is not dependantly typed, so cannot deal with types that depend on
values. This is why your code with tuples, and the HList code (which is
really doing the same thing through a defined API) both fall down on the
recursion.
One solution is to make all elements the same type and use lists... like:
   data Elem = ElemInt Int | ElemChar Char...
But this looses any static type checking. The alternative is to lift the 
values
to the type level, using something like Peano numbers to represent naturals:

data HZero = HZero
data HSucc x = HSucc x
Now different values have explictly different types, so we can have types
which depend on them...
Attached is an example implementation of times using this technique 
and the
HList library (its not debugged... so there might be some mistakes).

   Keean.

{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-overlapping-instances #-}
{-# OPTIONS -fallow-undecidable-instances #-}

module Joy where

import MainGhcGeneric1

data Lit a = Lit a 
instance Apply (Lit a) s (HCons a s) where
	apply (Lit a) s = HCons a s

data If = If
instance Apply t s s' = Apply If (HCons f (HCons t (HCons HTrue s))) s' where
	apply _ (HCons _ (HCons t (HCons _ s))) = apply t s
instance Apply f s s' = Apply If (HCons f (HCons t (HCons HFalse s))) s' where
	apply _ (HCons f (HCons _ (HCons _ s))) = apply f s

data Eq = Eq
instance TypeEq a b t = Apply Eq (HCons a (HCons b s)) (HCons t s) where
	apply _ (HCons a (HCons b s)) = HCons (typeEq a b) s

data Dip = Dip
instance Apply a s s' = Apply Dip (HCons a (HCons b s)) (HCons b s') where
	apply _ (HCons a (HCons b s)) = HCons b (apply a s)

data Dup = Dup
instance Apply Dup (HCons a s) (HCons a (HCons a s)) where
	apply _ s@(HCons a _) = HCons a s

data Pop = Pop
instance Apply Pop (HCons a s) s where
	apply _ (HCons _ s) = s

data Swap = Swap
instance Apply Swap (HCons a (HCons b s)) (HCons b (HCons a s)) where
	apply _ (HCons a (HCons b s)) = HCons b (HCons a s)

class (HNat a,HNat b) = HAdd a b c | a - b - c where
	hadd :: a - b - c
instance HAdd HZero HZero HZero where
	hadd _ _ = hZero
instance HAdd HZero (HSucc b) (HSucc b) where
	hadd _ b = b
instance HAdd a b c = HAdd (HSucc a) (HSucc b) (HSucc (HSucc c))
	hadd _ _ = hadd (undefined::a) (undefined::b)

data Add = Add
instance HAdd a b c = Apply Add (HCons a (HCons b s)) (HCons c s) where
	apply _ (HCons _ (HCons _ s)) = HCons (hadd (undefined::a) (undefined::b)) s

data Mult = Mult
instance HMult a b c = Apply Mult (HCons a (HCons b s)) (HCons c s) where
	apply _ (HCons _ (HCons _ s)) = HCons (hadd (undefined::a) (undefined::b)) s

data a @ b = a @ b
instance (Apply a s s',Apply b s' s'') = Apply (a @ b) s'' where
	apply (O a b) s = apply b (apply a s :: s')

type Square = Dup @ Mult
type Cube = Dup @ Dup @ Mult

data I = I
instance Apply a s s' = Apply I (HCons a s) s' where
	apply _ (HCons a s) = apply a s

data Times = Times
instance Apply Times (HCons p (HCons HZero s)) s where
	apply _ (HCons _ s) = s
instance Apply p s s' = Apply Times (HCons p (HCons (HSucc n) s) (HCons p (HCons n s')) where
	apply _ (HCons p (HCons _ s)) = HCons p (HCons (undefined::n) (apply p s))

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


  1   2   3   4   >