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


[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


[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-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: [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


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-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: [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


Re: [Haskell-cafe] Joy Combinators (Occurs check: infinite type)

2005-03-09 Thread Keean Schupke
Greg Buchholz wrote:
Keean Schupke wrote:
 

Haskell is not dependantly typed, so cannot deal with types that depend on
values.
   

   Can anyone recommend a nice dependently typed language to play with?
Cayenne, Epigram, other?
I have refactored your code into a type level Haskell program.
This has the nice advantage that it is extensible. You can add a new
primitive to the language as:
data PrimName
primName :: PrimName
primName = undefined
instance Apply PrimName a b where
   apply _ a = {- method implementing primName -}
Programs are assembled as types like:
   fac4 = lit nul `o` lit suc `o` lit (dup `o` pre)
   `o` lit mult `o` linrec
Recursion requires a primitive to aviod infinite types, see
definitions of times, linrec and genrec.
programs are run by applying the contructed type representing the
program to a stack... for example:
   putStrLn $ show $ apply (lit hThree `o` fac4) hNil
We could have written this:
   putStrLn $ show $ apply fac4 (hCons hThree hNil)
I have attached the debugged code, simply load into ghci, in the same
directory as the HList library (download http://www.cwi.nl/~ralf/HList)
as Joy.hs.
   ghci -fallow-overlapping-instances Joy.hs
(you need the flag to get the code to run interactively, however you
dont need the flag just to run 'main' to perform the factorial tests)
Keean.
  
  

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

module Joy where

import MainGhcGeneric1

type HOne = HSucc HZero
hOne :: HOne
hOne = undefined
type HTwo = HSucc HOne
hTwo :: HTwo
hTwo = undefined
type HThree = HSucc HTwo
hThree :: HThree
hThree = undefined

data Lit a
lit :: a - Lit a
lit = undefined
unl :: Lit a - a
unl = undefined
instance HList s = Apply (Lit a) s (HCons a s) where
	apply a s = hCons (unl 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 (Apply b s r,HHead r b',HIfte b' t f s s')
	= Apply Ifte (HCons f (HCons t (HCons 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 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 (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 (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 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 HList s = Apply Pop (HCons a s) s where
	apply _ (HCons _ s) = s

data Swap
swap :: Swap
swap = undefined
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 (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 (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 (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 (HSucc a) (HSucc b) (HSucc (HSucc c)) where
	hAdd _ _ = hSucc $ hSucc $ hAdd (undefined::a) (undefined::b)

data Sub
sub :: Sub
sub = undefined
instance (HList s,HSub a b c) = Apply Sub (HCons b (HCons a s)) (HCons c s) where
	apply _ (HCons _ (HCons _ s)) = hCons (hSub (undefined::a) (undefined::b)) s

class (HNat a,HNat b) = HSub a b c | a b - c where
	hSub :: a - b - c
instance HSub HZero HZero HZero where
	hSub _ _ = hZero
instance HNat a = HSub (HSucc a) HZero (HSucc a) where
	hSub a _ = a
instance HNat a = HSub HZero (HSucc a) HZero where
	hSub _ _ = hZero
instance (HSub a b c) = HSub (HSucc a) (HSucc b) c where
	hSub _ _ = hSub (undefined::a) (undefined::b)
	
data Mult
mult :: Mult
mult = undefined
instance (HList s,HMult a b c) = Apply Mult (HCons a (HCons

Re: [Haskell-cafe] tuples and Show in GHC

2005-03-07 Thread Keean Schupke
Remi Turk wrote:
On Mon, Mar 07, 2005 at 12:05:41AM +, Keean Schupke wrote:
 

Daniel Fischer wrote:
   

The Show instances for tuples aren't automatically derived, they are 
defined in GHC.Show. So somewhere there must be an end, probably the 
author(s) thought that larger tuples than quintuples aren't used often 
enough to bother. That's not a principled reason but a practical one, but 
it's good enough for me.
If you need them frequently and don't want to define your own instances, 
complain.
BTW, tuples are defined in Data.Tuple up to 62-tuples and Eq and Ord 
instances are derived up to 15-tuples.
In Hugs, apparently they are only provided up to quintuples.

 

Has there been any work done on declaring instances over all tuples? It 
seems the pattern occurs fairly often, and is quite simple to abstract.

  Keean.
   

Which almost sounds like a hint to replace the current tuples by
HLists in Haskell 2? ;)
Something like:
infixr 5 :*:
data HNil = HNil
data HList b = a :*: b = a :*: !b deriving (Eq, Ord)
-- type () = HNil
type (a,b) = a :*: b :*: HNil
type (a,b,c) = a :*: b :*: c :*: HNil
fst :: HList b = (a :*: b) - a
fst (a:*:b) = a
Where (x,y,z) is syntactic sugar for x :*: y :*: z :*: HNil in
much the same way [x,y,z] is syntactic sugar for x:y:z:[]...
It might even be (almost?) backward compatible AFAICS.
Groeten,
Remi
 

Whilst thats certainly one way to do it, HLists are composed of binary 
products (,)...  So this
works as long as you can imagine: (a,(b,(c,HNil))) == (a,b,c)

We can define the operations generically using HLists, and we can even 
convert back and
forth from a tuple to an HList (for a limited number of tuple instances).
Infact we might be able to do conversion of arbitrary tuples using 
template-haskell.

   Keean.
___
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-07 Thread Keean Schupke
Daniel Fischer wrote:
And, BTW, that's why Keean et al's HList library doesn't help here either, the 
type of an HList determines the number of elements and the type of each, so 
there we face the same problems as with nested tuples. What we need is 
type Stack = [ArbitraryType] (from the HList paper, I surmise that [Dynamic] 
would be possilble, but that seems to have it's own problems).

 

Well it depends on what you want to do... If the types of elements are
determined by the computation then you can use an HList as is, and there
is no problem.
The only time there is a problem is if the _type_ of an element to be put
in an HList depends on an IO action. In this case you need to existentially
quanify the HList.
So you can use the HList in both cases, but you have to deal with 
existential
types if the type of the HList is dependant on IO (you dont have to do this
if only the value of an element depends on IO).

   Keean.
___
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-06 Thread Keean Schupke
Daniel Fischer wrote:
I don't know Joy, but probably there the stack is (roughly) a heterogenous 
list, which is hard to model in Haskell, think of

data Element = Bool Bool
 | Char Char
 | Int Int
  . . .
 | IntToBool (Int - Bool)
  . . .
type Stack = [Element]
and how to define functions for that, urgh.
 

Not saying it isn't tricky - but thats what the HList library 
(http://www.cwi.nl/~ralf/HList) implements, a heterogenous list.
It works slightly differently using classes, but does abstract the
workings enough to be useful, to construct an HList you can do:

hlist = a .*. (3:Int) .*. False .*. 'v' .*. HNil
And provides head/tail functions and other useful list and set
operators.
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] tuples and Show in GHC

2005-03-06 Thread Keean Schupke
Daniel Fischer wrote:
The Show instances for tuples aren't automatically derived, they are defined 
in GHC.Show. So somewhere there must be an end, probably the author(s) 
thought that larger tuples than quintuples aren't used often enough to 
bother. That's not a principled reason but a practical one, but it's good 
enough for me.
If you need them frequently and don't want to define your own instances, 
complain.
BTW, tuples are defined in Data.Tuple up to 62-tuples and Eq and Ord instances 
are derived up to 15-tuples.
In Hugs, apparently they are only provided up to quintuples.

Has there been any work done on declaring instances over all tuples? It 
seems the pattern occurs fairly often, and is quite simple to abstract.

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


Re: [Haskell-cafe] how do I avoid excessive constructor application?

2005-03-02 Thread Keean Schupke
Something like:
class Coerce a b where
   coerce :: a - b
The class must be in a separate file from the instance so that the compiler
does not determine that a == b for all instances.
instance Coerce a a where
   coerce = id
If it turns out the left and right types do not match, you get a
no instance of coerce for ... error.
   Keean.

S. Alexander Jacobson wrote:
I'd like to do this sort of thing with types other than Either.
Is there a generic safe coerce function?
-Alex-
On Wed, 2 Mar 2005, Stefan Holdermans wrote:
Lemmih,
And you can fix it with some unsafeCoerce# magic. (:

Actually, as I pointed out, the required coercion in perfectly safe, 
though not implicit:

coerceRight :: Either a b - Either c b
coerceRight (Right b) = Right b
Regards,
Stefan
__
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


Re: [Haskell-cafe] Re: New to haskell: unresolved overloading question

2005-02-21 Thread Keean Schupke
There are problems with this approach... Instance heads are only chosen 
by the pattern not the constraints, so:

instance (Ord a, Num a) = ApproxEq a where x ~= y = (abs (x-y)  1)
Will match any type at all (whether a member of Ord or Num or not) and 
then will
fail if the particular type is not an instance of Ord or Num.

Using incoherent-instances is almost certainly broken as it just stops 
the compiler complaining is a generic instance (like above) overlaps 
with a specific instance in the wrong way. Using the flag just makes GHC 
silently choose the _most_generic_instance_. Almost alwaysApproxEq we 
want the opposite behaviour and want GHC to choose the most specific 
instance in the case of overlap.

However it should do what you want with just -foverlapping-instances 
-fundecidable-instances.
 

   Keean.
Christian Maeder wrote
Blair Fraser wrote:
I'm new to haskell and I'm working through the class section of the
gentle tutorial.  I decided to implement an ApproxEq class (just for
fun), but have run into problems.  The code below works fine for units
and bools, but gives an unresolved overloading error for Floats and
Doubles.  What's going on here?  What does the error message mean and
what did I do wrong?  (I'm in Hugs.)
-- ApproxEq: My first class.
class (Eq a) = ApproxEq a where
  (~=) :: a - a - Bool
  x ~= y = x == y -- By default, check equality
-- These two override default with same, just checking if it works
instance ApproxEq () where () ~= () = Trueinstance ApproxEq 
Bool where x ~= y = x == y

-- These two override default with different
--   consider floating points equal if they differ by one or less
instance ApproxEq Float where x ~= y = (abs (x-y) = 1)
instance ApproxEq Double where x ~= y = (abs (x-y) = 1)

More elegant seems to be:
instance (Ord a, Num a) = ApproxEq a where x ~= y = (abs (x-y)  1)
However, this requires extensions to Allow unsafe overlapping 
instances:

hugs -98 +O
ghci -fglasgow-exts -fallow-overlapping-instances 
-fallow-undecidable-instances -fallow-incoherent-instances

-- This one dosn't work either, but it just depends on the other two
instance ApproxEq a = ApproxEq [a] where
  [] ~= [] = True
  (x:xs) ~= (y:ys) = x ~= y  xs ~= ys
  _ ~= _ = False
Thanks,
Blair

___
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] What is MonadPlus good for?

2005-02-14 Thread Keean Schupke
Technically this is a use of MonadError, not MonadPlus (see earlier 
discussion about how IO is _not_ an instance of MonadPlus).

   Keean.
David Roundy wrote:
On Sat, Feb 12, 2005 at 01:08:59PM -0500, Benjamin Pierce wrote:
 

I have seen lots of examples that show how it's useful to make some type
constructor into an instance of Monad.
Where can I find examples showing why it's good to take the trouble to show
that something is also a MonadPlus?  (I know there are many examples of
things that *are* MonadPluses; what I want to know is why this is
interesting. :-)
   

I've been working on a typeclass that derives from MonadPlus which will
encapsulate certain kinds of IO.  With MonadPlus, you can write monadic
code with exceptions and everything that may not be executed in the IO
monad.  You just use fail to throw exceptions, and mplus to catch them.
class MonadPlus m = ReadableDirectory m where
   mInCurrentDirectory :: FilePath - m a - m a
   mGetDirectoryContents :: m [FilePath]
   mReadFilePS :: FilePath - m PackedString
   mReadFilePSs :: FilePath - m [PackedString]
   mReadFilePSs f = linesPS `liftM` mReadFilePS f
One instance of this class is IO, but I can also have instances for
in-memory data structures (outside the IO monad) or (or example) for
reading a tarball from disk--which would be a monad that acts within the IO
monad.
 

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


Re: [Haskell-cafe] What is MonadPlus good for?

2005-02-14 Thread Keean Schupke
[EMAIL PROTECTED] wrote:
G'day all.
Quoting David Roundy [EMAIL PROTECTED]:
 

It might be interesting to write a backtracking IO-like monad which
obeyed m  mzero === mzero.  I imagine you could do it for something like
an ACID database, if you define === as meaning has the same final result
on the database, which of course would only be useful if the database had
sufficient locking that it couldn't have been read between the original m
and the later mzero.
   

You should talk to the logic programming community about this some time.
As Lee Naish has pointed out on many occasions, it would involve finding a
way to insert the page back into the laser printer and lift the toner off.
 

Not quite... remember the IO monad is a function which returns an
IO program... as long as none of the IO program has been executed it
is possible to 'edit' the program to remove parts...
The problem only really occurs in interactive programs, where input
forces partial evaluation of the function result... once the function
has been evaluated up to the input the output so far cannot be
retracted.
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] File path programme

2005-01-27 Thread Keean Schupke
Ben Rudiak-Gould wrote:
I'm tentatively opposed to (B), since I think that the only 
interesting difference between Win32 and Posix paths is in the set of 
starting points you can name. (The path separator isn't very 
interesting.) But maybe it does make sense to have separate 
starting-point ADTs for each operating system. Then of course there's 
the issue that Win32 edge labels are Unicode, while Posix edge labels 
are [Word8]. Hmm.

Several assumptions here... We might want more platforms than 
windows/unix. The separator for these systems is different (\ for 
windows / for unix - who knows what other obscure systems may use).

It seems to me a type class would allow the user to add definitions for 
their platform (IE it is extensible)... datatypes tend to be hard to 
extend as you have to find every use in the code
and modify it.

For code to be portable it has to use a diffenernt path parser depending 
on the platform, but
the code must not be different... One way of doing this would be to use 
a class...

   data Windows
   data Unix
   type System = Unix
   class ParsePath a where
  parsePath' :: a - String - Path
   instance ParsePath Windows where
  parsePath' _ a = ...
   instance ParsePath Unix where
  parsePath' _ a = ...
If all paths can be expressed in a single type, it seems different path 
parsers and printers are required. All the other functions could operate 
on the standard datatype. This still leaves the
problem of determining what system you are compiling on... I guess I 
still don't see the problem with having:

   #ifdef Unix
  type System = Unix
   #endif
   #ifdef Windows
  type System = Windows
   #endif
In some library somewhere... Infact its the only way I can see of 
selecting the correct
instance at compile time... and using classes is the only way I can 
think of making the
system easily extensible (even if we use a single datatype for all paths)

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


Re: [Haskell-cafe] File path programme

2005-01-27 Thread Keean Schupke

I guess it's just that I'm more concerned with making possible what is
currently impossible (according to the library standards)--that is, using
FFI and IO on the same file--rather than just adding utility features that
application developers could have written themselves.  I suppose we don't
need a class for this, all we need is a couple of functions to convert
between FilePath and CString.
 

Except paths are different on different platforms... for example:
/a/b/../c/hello\ there/test
and:
A:\a\b\
notice how the backslash is used to 'escape' a space or meta-character on
unix, but is the path separator for windows. If you want to write portable
applications, then you dont want to hard code the platform type. So 
converting
from the datatype to a string is not simple:

   string = pathToString ...
one way of doing this is to have pathToString call a function to 
determine the
system type and construct the string accordingly. The problem here is 
that it is
not extensible by the user, the supported platforms are determined by 
the library.
By using a class we can let the user define translations for new 
platforms...

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


Re: [Haskell-cafe] File path programme

2005-01-27 Thread Keean Schupke
Jules Bean wrote:
only it isn't. That's a property of a shell, the underlying OS allows 
spaces in file names with no need for an escaping mechanism.
Okay, that was a mistake... but it does not change the point, that 
pathToString needs to work out what platform it
is on, and doing it without typeclasses makes it not extensible.

We need a way of allowing people to define new path printers (as members 
of a class)... whilst having the program
determine which platform it is on, and choosing the correct instance (at 
compile time).

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


Re: [Haskell-cafe] Re: Visual Programming Languages

2005-01-26 Thread Keean Schupke
Hmm, can't resist commenting on this one!
Bayley, Alistair wrote:
This was odd...
Some cherry-picked quotes from the manifesto:
 http://alarmingdevelopment.org/index.php?p=5
- Visual languages are not the solution: ... common idea is to replace AST
structures with some form of graphical diagram. ...
 

Agree, point and grunt is much slower than entering commands. Its like 
being stuck in a country where you don't speak the language - all you 
can do is point at things and grunt ('click') and hope they understand you.

- Programming is not Mathematics
 

Disagree strongly... Bad programming seems to have little to do with 
mathematics, good programming often has the elegance of a well thought 
out proof. Beauty in programming is like beauty in mathematics.

- Change is natural: There has been much effort expended to remove the
concept of mutable state from programming, to be replaced by immutable
values as in mathematics. This is entirely misguided. ... Monads are a
reductio ad absurdum.  [ Heresy! :-) ]
 

Change is natural, but that has nothing to do with mutable state.
Parallelism will make mutable state less attractive, as will
hardware/software co-design. Isolating changes within a verifiable
sandbox (like the ST/State monads) reduces errors due to unforseen
interactions.
- Control flow considered harmful:  ... The primary reason for this is to
permit side-effects to be ordered by the programmer. ... [ This appears to
contradict the criticism of monads. ]
 

Agree - control flow causes the possible paths (or corner cases) in the
program to increase exponentially. Program correctness verification becomes
much harder with more possible-paths.
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-25 Thread Keean Schupke
Daniel Fischer wrote:
I think, 1. should be acceptable to everybody, and 2. as a principle too, only 
the question of which effects are relevant needs to be answered. It's plain 
that not all measurable effects are relevant. My inclination to ignore the 
side-effects stemmed from the (irrational) desire to have IO's MonadPlus 
instance justified, now I'm prepared to say yes, side-effects such as output 
do count, so the instance MonadPlus IO is erroneous, but may be maintained 
for practical reasons.

 

I am sure monads in Haskell (and other functional languages like ML) are 
defined
on types not values. Therefore it only matters that the types are 
correct and that
the operator obeys the associative laws. I am reasonably sure the values 
whether
returned or side-effects are irrelevent.

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-25 Thread Keean Schupke
I think I see, but if the objects are types, arn't the morphisms functions
on types not values?
   Keean.
Ashley Yakeley wrote:
In article [EMAIL PROTECTED],
Keean Schupke [EMAIL PROTECTED] wrote:
 

I am sure monads in Haskell (and other functional languages like ML) are 
defined on types not values.
   

The objects of the category are types. The morphisms on the category are 
functions. Two functions are the same if they match each value to the 
same value. For the Functor laws and the Monad laws, the values 
certainly do matter: if they didn't, they wouldn't correspond to the 
category theory notions of functor and monad because the morphisms would 
be wrong.

 

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-25 Thread Keean Schupke
Jules Bean wrote:
No. Well: they are functions 'on' types, but functions 'on' types map 
values to values.

Analogy: In the category of sets and functions, the objects are sets 
and the morphisms are functions. The functions --- from sets to sets 
--- take objects in one set to objects in another set.

Specifically:
A monad T is a (endo)functor T : * - * where * is the category of 
types, together with a multiplication mu and a unit eta.
So, * is the category of Types, and functions on type (which map values 
to values), and T is
an endofunctor (mapping functions on type to functions on type).

How does this affect the IO monad though?
   m = (\a - mzero) === mzero
If we consider the state monad, surely the above makes no comment on what
the final state should be, only the final value returned...
Or is MonadPlus not definable on State monads?
If it is then considering IO === ST RealWorld, would imply that the actions
of the IO monad are not important as long as the final value returned is
mzero?
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-25 Thread Keean Schupke
Jules Bean wrote:
Well, mzero isn't a return value in the IO monad, it's an exception.  
But yes, I agree with you that the (plausible) laws I have seen for 
MonadPlus seem to say that mzero should ignore the actions. But this 
in practice is not how IO behaves.

Jules
I can see three possible solutions:
   1) IO is not an instance of MonadPlus (but may still be an instance 
of MonadError)
   2) Side effects are ignored (or state is ignored) and IO may be an 
instance of MonadPlus

   3) bind (=) is redefined for IO. As the IO Monad is a function 
which resturns a computation,
   bindIO can be changed such that (a  mzero === mzero). In other 
words if the RHS is mzero, the
   LHS is not included in the final result (and its actions would not 
get executed), however this
   must be inconsistent if we consider:

  f = getChar = (\a - if a == F then mzero else return a)
   In this case if the LHS returns F the LHS should not have been 
run... this contradicts itself, so
   this is a non option I guess.

Acutally looking at GHC CVS libraries, there is not a definition for 
MonadPlus on the state or IO
monads...

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-25 Thread Keean Schupke
Jules Bean wrote:
It's in Control.Monad.Error. Not documented though.
Jules
Ahh, so it is:
instance MonadPlus IO where
   mzero   = ioError (userError mzero)
   m `mplus` n = m `catch` \_ - n
So, the author of this obviously subscribed to the view that 
side-effects are not
counted when considering function identity...

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-24 Thread Keean Schupke
Ashley Yakeley wrote:

If you remember your category theory, you'll recall that two morphisms 
are not necessarily the same just because they're between the same two 
objects. For instance, the objects may be sets, and the morphisms may be 
functions between sets: morphisms from A to B are the same only if they 
map each element in A to the same element in B.
 

Yes, but I though the 'objects' in this case are endofunctors from a 
type to itself... the the morphisms operate on these endofunctors, the 
morphisms are unit and join such that joining 'unit' to the 
endofuntor retults in the endofunctor.

But I think that as the endofunctor is from the type to itself, the 
value does not
come into it.

   A - A `join` unit  = A - A
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-24 Thread Keean Schupke
Jules Bean wrote:
I've lost track of what you mean by 'this case' and indeed of what you 
mean by 'join' (did you mean mplus? the word join is normally used for 
the operation of type m (m a) - m a, which is not often used directly 
in haskell)

However, even addressing your point about endofunctors: for two 
endofunctors to be equal, they must be equal on all objects and all 
morphisms, which effectively means they must be pointwise equal on all 
values.

Jules
I think the endofunctors are defined on the types, not the values 
though. So the object of the category is the endofunctor (Type - Type), 
and unit and join are the identity and binary associative operator on 
which a Monad is defined. return and bind are defined in terms of unit 
and join. So unit is the identity which when joined to the endofunctor 
(Type - Type) results in the same endofunctor... Therefor:

   (Type - Type) `join` unit = (Type - Type)
Now as the type of the IO monad is IO a we end up with:
   (IO a - IO a) `join` unit = (IO a - IO a)
This is true irrespective of any side effects IO may have, as the type 
is the
same for the IO action no matter what side effects it generates.

At least thats how I understand it...
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: File path programme

2005-01-24 Thread Keean Schupke
Marcin 'Qrczak' Kowalczyk wrote:
These rules agree on foo, foo. and foo.tar.gz, yet disagree on
foo.bar.; I don't know which is more natural.
 

Filename extensions come from DOS 8.3 format. In these kind of
names only one '.' is allowed. Unix does not have filename extensions,
as '.' is just a normal filename character (with the exception of
'.', '..', and filenames starting with a '.' which are hidden files).
As far as I know unix utilities like gzip look for specific extensions 
like '.gz',
so it would make more sense on a unix platform to just look for a filename
ending '.gz'... this applies recursively so:

fred.tar.gz
Is a tarred gzip file, so first ending is '.gz' the next is '.tar'...
So as far as unix is concerned:
foo.bar. is just as it is... as would any other combination unless the 
extension
matches that specifically used by your application...

So the most sensible approach would be to have a list of known 
extensions which can be
recursively applied to the filenames, and leave any other filenames alone.

[.gz,.tar,.zip] ...
In other words just splitting on a '.' seems the wrong operation. 
(Imagine gziping a file
called a... you get agz, in other words simply an appended .gz)

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-24 Thread Keean Schupke
Ashley Yakeley wrote:
I disagree. Clearly (putStrLn Hello  mzero) is not the same as mzero.
 

Yes it is, side effects are quite clearly not counted. The value
of (putStrLn Hello  mzero) is mzero.
In reference to the idea of splitting MonadPlus, what category
would you be operating in, if you have a zero but no co-product
operation?
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-24 Thread Keean Schupke
Just thinking about this, a monad is a Functor plus two 
natural-tranformations, Unit and Join. Is there an equivalent definition 
for MonadPlus... I am not sure I understand where MonadPlus comes from? 
Is it just a Functor and two different definitions of Unit and Join 
(from those chosen to be in the class Monad?)

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-24 Thread Keean Schupke
Ashley Yakeley wrote:
I don't believe this represents a good understanding of IO actions as 
Haskell values. For instance, 'return ()' and 'putStrLn Hello' are the 
same type, but are clearly different actions and so are usually 
considered to be different values. That the latter prints out text might 
be better considered not so much a side effect as the actual action 
itself.

You've introduced the concept of the value of an IO action, apparently 
as something separated from side effects. I don't believe you can 
properly define this. For instance, what is the value of getChar such 
that it doesn't involve side effects?

 

Right, but we are dealing with the type system here. Remember Haskell
monoids are functors on types, not on values ... (ie the base objects the
'category theory' is applied to are the types not the values)...
Therefore we only consider the types when considering Monads.
As such if you wished to consider the examples you gave distinct, the
type system would need to distinguish side effects... this can be
done with a linear-aliasing type system, but not Haskell's as far as I 
know...
Maybe you could write such types:

   {putStrLn Hello; mzero} :: IO (PutStrLn Hello = ()) ???
But if we look at the type of the Functor:
   fmap :: (a - b) - m a - m b
Where is the IO action?
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-23 Thread Keean Schupke
Jorge Adriano Aires wrote:
On the list monad, I think of the mplus operation as the union two 
non-deterministic states. Mzero is the state that works as the identity 
(which is when you have no possible state at all). 
 

Okay... thats a definition of a monoid.
What would happen if this was the definition?
instance MonadPlus [] where
  mzero = []
  mplus a b
  | a == [] = b
  | otherwise = a
   

Isn't the above a monoid as well?
   a `mplus` [] = a
   [] `mplus` b = b
Still looks like an identity to me
Is there only on correct definition of a monad/monoid on lists - or does 
anything that satisfies the monad laws count? I got the impression you 
could define anthing you liked for mzero and mplus - providing the laws 
are upheld?

Then, I'd say you're not thinking of monadic sums, but of catching errors, and 
the appropriate place for that is the class MonadError. 
 

I am thinking about how some monads are summed - like Maybe and
the Parser monad.
It seems there are two possibilities - either the definitions of MonadPlus
for Maybe and Parser monads are in Error, or there can be two different
acceptable definitions of MonadPlus on the List?
   Keean
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-23 Thread Keean Schupke
Aaron Denney wrote:
You can, but the other one turns it into a copy of the Maybe Monad, so
the current one is more useful.
 

So what does this mean in terms of Ashley's question:
But only some instances (such as []) satisfy this:
(mplus a b) = c = mplus (a = c) (b = c)
Other instances (IO, Maybe) satisfy this:
mplus (return a) b = return a
Does it mean that both fall within the acceptable definition of the monad laws
for MonadPlus?
  1. |mzero = f == mzero|
  2. |m = (\x - mzero) == mzero|
  3. |mzero `mplus` m == m|
  4. |m `mplus` mzero == m|
So I guess I must have missed the point because the distinction between say a monad on
[] and Maybe for example seems to me to be irrelevant to MonadPlus. The distinction comes
down to mplus being the same as skipError for Maybe and different for []. 

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


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-23 Thread Keean Schupke
Ashley Yakeley wrote:
I think it would be helpful if all these classes came with their laws
prominently attached in their Haddock documentation or wherever. The 
trouble with MonadPlus is that the precise set of associated laws is 
either unspecified or not the most useful (I assume there's a paper on 
the class somewhere). I think everyone can agree on  these:

 mplus mzero a = a
 mplus a mzero = a
 mplus (mplus a b) c = mplus a (mplus b c)
 

I think it would be even better if the classes came with assertions
that 'enforced the laws'... I think this requires dependant types
though.
 mzero = a = mzero
But what about this?
 a  mzero = mzero
 

Well it was in the list I saw... I we consider the familar arithmetic 
product
a * b * 0 -- it is clear that an mzero anywhere in a sequence should result
in mzero:

a  b  mzero  c  d = mzero
But that says nothing about the co-product... where mzero should be the
identity IE:
a `mplus` mzero = a
mzero `mplus` a = a
But I am not sure there are any requirements on commutivity or associativity
on the co-product operation?
It's satisfied by [] and Maybe, but not IO (for instance, when a is 
'putStrLn Hello'), but IO has been declared an instance of MonadPlus. 
And then there are the two I gave:
 

 (mplus a b) = c = mplus (a = c) (b = c)
 

This was not on the list I saw - guess it could either be an omission,
or it has nothing to do with MonadPlus ... monads with identity and
co-product?
...which is satisfied by [], but not Maybe or IO.
 mplus (return a) b = return a
...which is satisfied by Maybe and IO, but not [], although your 
alternative declaration would make [] satisfy this and not the previous 
one.
 

But one could make up any arbitrary law that is satisfied by some
definition of a Monad and not others. Presumably there has to be
some sound category-theoretic reason for including the law?
   Keean
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-22 Thread Keean Schupke
Ashley Yakeley wrote:
In article [EMAIL PROTECTED],
S. Alexander Jacobson [EMAIL PROTECTED] wrote:
 

I assume there is a standard name for this 
class/function:

  instance Foo [] where
foo [] = mzero
foo (x:_) = return x
  instance Foo (Maybe x) where
foo Nothing = mzero
foo Just x = return x
   

Surely they are incomplete monad definitions (has a return but no bind)...
I don't believe so. I had to write my own classes to do this sort of 
thing.

This is also a good opporunity to point out an ambiguity in the standard 
MonadPlus class. All instances satisfy these:

 mplus mzero a = a
 mplus a mzero = a
But only some instances (such as []) satisfy this:
 (mplus a b) = c = mplus (a = c) (b = c)
Other instances (IO, Maybe) satisfy this:
 mplus (return a) b = return a
I think mplus should be separated into two functions. This code shows 
the difference a bit more clearly:

 do
   b - mplus (return True) (return False)
   if b then mzero else return ()
For the first kind this is the same as return (), for the second kind 
it's the same as mzero.
 

But isnt the point of Monad plus, that to have a 'zero' implies failure 
(a normal
monad cannot fail) - and failure implies choice (a `mplus` b) is a if a 
succeeds or
b if a fails and b succeeds,or mzero if both fail. if you look at your 
first identity:

   mplus mzero a = a
   mplus a mzero = a
This fits the above description, but I don't see how the following can 
be true:

   (mplus a b) = c = mplus (a = c) (b = c)
The LHS says (if a fails run b)  then run c.
The RHS says if (a then c) fails  run (b then c)
Finally,
mplus (return a) b = return a
Is obvious because return a is not  mzero, so it is true for all 
Monads that can fail. 

Or have I missed the point?
   Keean.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: what is inverse of mzero and return?

2005-01-22 Thread Keean Schupke
Ashley Yakeley wrote:
In article [EMAIL PROTECTED],
Keean Schupke [EMAIL PROTECTED] wrote:
 

This fits the above description, but I don't see how the following can 
be true:

   (mplus a b) = c = mplus (a = c) (b = c)
   

Try it (and my test code) with [], which is an instance of MonadPlus. 
mplus is defined as (++) for [].

 

but what if (a = c) causes c to fail, and (b = c) lets c succeed. In 
this
case the LHS will fail, whereas the RHS will succeed I think?

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


  1   2   3   >