Re: [Haskell] ANNOUNCE: set-monad

2012-06-16 Thread Derek Elkins
On Sat, Jun 16, 2012 at 3:47 AM, Dan Burton  wrote:
>
> Convenience aside, doesn't the functor instance conceptually violate some 
> sort of law?
>
> fmap (const 1) someSet
>
> The entire shape of the set changes.
>
> fmap (g . h) = fmap g . fmap h
>
> This law wouldn't hold given the following contrived ord instance
>
> data Foo = Foo { a, b :: Int }
> instance Ord Foo where
>   compare = compare `on` a
>
> Given functions
>
> h foo = foo { a = 1 }
> g foo = foo { a = b foo }
>
> Does this library address this? If so, how? If not, then you'd best note it 
> in the docs.

Your hypothesis is false.  You should at least try out your example.
It's easy to show that (fmap g . fmap h) x is true for all x (at least
ignoring potential issues with strictness.)  The thing to note is that
fmap h x is not a set, it is an expression tree (which is only
observable via run.)  The law that ends up failing is toList .
fromList /= id, i.e. fmap g . toList . fromList . fmap h /= fmap g .
fmap h

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


[Haskell] ANNOUNCE: Parsec 3.1.0

2010-03-03 Thread Derek Elkins
Parsec is a monadic combinator library that is well-documented, simple
to use, and produces good error messages.   Parsec is not inherently
lazy/incremental and is not well-suited to handling large quantities
of simply formatted data.  Parsec 3 adds to Parsec the ability to use
Parsec as a monad transformer and generalizes the input Parsec
accepts.  Parsec 3 includes a compatibility layer for Parsec 2 and
should be a drop-in replacement for code using Parsec 2.  Code using
the features of Parsec 3 should use the modules in Text.Parsec.

Due almost entirely to the work of Antoine Latter there is a new
version of Parsec 3 available.  He documented some of his thoughts on
this in this series of blog posts:
http://panicsonic.blogspot.com/2009/12/adventures-in-parsec.html

The main features of this release are:
- the performance should be much better and comparable to Parsec 2
- notFollowedBy's type and behavior have been generalized

Changes:
- the changes to the core of Parsec lead to some changes to when
things get executed when it is used as a monad transformer
"In the new version bind, return and mplus no longer run in
the inner monad, so if the inner monad was side-effecting for these
actions the behavior of existing code will change."
- notFollowedBy p now behaves like notFollowedBy (try p) which
changes the behavior slightly when p consumes input, though the
behavior should be more natural now.
- the set of names exported from Text.Parsec.Prim has changed somewhat
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Top Level <-

2008-08-26 Thread Derek Elkins
On Tue, 2008-08-26 at 19:01 +0400, Bulat Ziganshin wrote:
> Hello Ashley,
> 
> Monday, August 25, 2008, 3:12:18 AM, you wrote:
> 
> > Is there any interest in implementing a top level "<-" to run monadic code?
> 
> yes, definitely. as it's hard to develop "real" app w/o using global
> vars, h98 still remains "unreal" language
> 
> but from my POV it's important to push this feature into haskell
> standard

Haskell should be moving -toward- a capability-like model, not away from
it.

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


[Haskell] ANN: Parsec 3.0.0

2008-03-05 Thread Derek Elkins
This is a first release of the Parsec 3, the Google Summer of Code of
Paolo Martini.

The main changes are:
* The Parser monad has been generalized into a ParserT monad
  transformer.

* The parsers have been generalized to work over a stream of any 
  type, in particular, with byte strings.

* There is Haddock documentation for almost all functions in the 
  Text.Parsec tree.

* The Parser monad now has Applicative/Alternative instances

* A "compatibility" Text.ParserCombinators.Parsec tree for the old 
  Parsec.  It's not perfect, but it should work with most Parsec 2
  code.

This package should be installable from with cabal install or with the
standard cabal invocations.

Cabal release:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsec-3.0.0

The darcs repository is at:
http://code.haskell.org/parsec3

Note that this package is a new version of the parsec package and so
will hide the old parsec-2.1.0.0 package.

I would like to thank Antoine Latter for a variety of significant
patches including updating the compatibility modules and a large effort
testing them.

[P.S. I will probably be lacking an Internet connection over the next
few days.]

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


Re: [Haskell] Should the following program be accepted by ghc?

2008-01-16 Thread Derek Elkins
On Wed, 2008-01-16 at 09:18 +, J.N. Oliveira wrote:
> On Jan 16, 2008, at 2:08 AM, Bruno Oliveira wrote:
> 
> > Hello,
> >
> > I have been playing with ghc6.8.1 and type families and the  
> > following program is accepted without any type-checking error:
> >
> >> data a :=: b where
> >>Eq :: a :=: a
> >
> >> decomp :: f a :=: f b -> a :=: b
> >> decomp Eq = Eq
> >
> > However, I find this odd because if you interpret "f" as a function  
> > and ":=:" as equality, then this is saying that
> >
> > if f a = f b then a = b
> 
> This is saying that  f  is injective. So perhaps the standard  
> interpretation leads implicitly to this class of functions.

Just like data constructors, type constructors are injective. f a
doesn't simplify and so essentially you have structural equality of the
type terms thus f a = f b is -equivalent- to a = b.  Obviously type
functions change this, just like normal value functions do at the value
level.

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


Re: [Haskell] Bang patterns and declaration order

2007-11-18 Thread Derek Elkins
On Sun, 2007-11-18 at 12:11 -0800, Iavor Diatchki wrote:
> Hello,
> 
> I was playing around with "bang patterns" and I noticed that
> when combined with asynchronous exceptions they can lead to
> programs where the order of the declarations in a binding
> group is important!  Here is an example:
> 
> > import Control.Exception
> > import Prelude hiding (catch)
> >
> > main = putStrLn =<< eval_order
> >
> > test = "no exception"
> >   where !_ = error "top down"
> > !_ = error "bottom up"
> >
> > eval_order = evaluate test `catch` \e ->
> >case e of
> >  ErrorCall txt -> return txt
> >  _ -> throw e
> 
> Of course, this is a contrived exampled but, as far as I know,
> this was not possible in Haskell before (if anyone has an example
> to the contrary please send it to the list).
> 
> By the way, with GHC 6.8.1 the above program prints "bottom up".
> This means that when there are multiple "banged" bindings they
> are evaluated starting with the last one in the text.  I imagine
> than in most programs this is not particularly important, but
> it seems to me that it would be a bit nicer if we were to adjust
> the translation so that bindings were evaluated top to bottom
> (e.g., like in ML).

The whole point of the "imprecise exceptions" paper was that any
exception may be returned when multiple ones could be.  There is no
reason why the bindings should be evaluated top-down.  If you are
relying on the order the bindings are evaluated you are doing something
very, very wrong.  Should we also specify what exception should be
thrown for  error "left-right" + error "right-left" ?

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


[Haskell] AmeroHaskell

2007-11-17 Thread Derek Elkins
[Reply-To set to Haskell-Cafe]

At http://www.haskell.org/haskellwiki/AmeroHaskell is a page for a
proposed Haskell meeting originally aimed for the south eastern United
States.  Quite a few people registered interest, but few of them were in
the SE.  This email is to prompt any more interest in such a meeting
without any fixed geographical locale.  To get an idea of what it would
be like, it would be something along the lines of
http://www.haskell.org/haskellwiki/AngloHaskell

Anyone interested in an Haskell meeting anywhere in America mark your
interest and what region would be good for you.  Anyone who could
provide a venue would also be highly appreciated.  It may well end up
being AmeroHaskells with several meetings in different regions.

However, to put things in motion for something concrete at all, we're
hoping to put together a meeting taking place in the Portland area as
that seems most convenient to the most people who had registered
interest in AmeroHaskell and an easy place to find a venue.  In that
vein, while no plans have been made, something aimed for the
January/February time-frame and probably hosted by Galois, if they are
willing, has been discussed.

The event would probably be a few days long and would involve some
informal (and perhaps impromptu) talks and hanging out, getting to know
each other as more than an IRC handle, and some cooperative hacking.
Again, see the AngloHaskell page for an idea.  Anyone who is interested
in presenting a talk about anything they are doing or are interested in
in Haskell or Haskell-related topics please suggest that on the wiki
page or reply here!  Admittedly a January/February time-frame does not
provide a lot of head time, but the talks are aimed at a friendly chat
tone rather than a formal presentation.  Feel free to bring your
half-baked ideas.

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


Re: [Haskell] Power series in a nutshell

2007-07-12 Thread Derek Elkins
On Thu, 2007-07-12 at 12:49 -0400, Doug McIlroy wrote: 
> For lovers of things small and beautiful,
> http://www.cs.dartmouth.edu/~doug/powser.html
> boils down basic operations on power series with numeric
> coefficients to the bare minimum--each is a one-liner.
> Included are overloaded arithmetic operators, integration,
> differentiation, functional composition, functional inverse
> and coercion from scalars. --A telling demonstration of the
> power of lazy evaluation and of Haskell's attunement to math.

and a link to your earlier Functional Pearl,
http://citeseer.ist.psu.edu/mcilroy98power.html

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


Re: [Haskell] Re: ANNOUNCE: Harpy -- run-time code generation library

2007-05-14 Thread Derek Elkins

Dirk Kleeblatt wrote:

apfelmus wrote:

Note that even currently, your operations cannot be strict in the
address a label refers to because this may be determined later than the
first use of the label. In other words, your example code

  fac = do

[...]

(1)   jmp  loopTest

[...]

(2)   loopTest @@ cmp ecx (0 :: Word32)

[...]

already shows that the function jmp that generates a jmp-instruction may
not be strict in the position it jumps to as the address behind loopTest
is only known later at line (2).


When generating code for (1), the label loopTest is used as an index 
into a map, to see whether there's a code position associated with it. 
If it is, the code position is used to compute the jump offset for the 
jmp instruction, if not (as in this example), a dummy value is placed in 
the code buffer, and Harpy remembers this position to be patched later 
on. At (2), the label is defined, and this leads to patching all 
instructions that have been emitted before this definition.


So, yes, the code position is only used after the definition of the 
label. But the "look up in a map"-part makes the jmp operation strict in 
the label parameter.


We could omit the map, and just remember where to patch the code, but 
then we'd need to call explicitly some function after code generation 
that does the patching. We had implemented this, but found the current 
solution easier to use, since backpatching is completely automatic and 
hidden from the user.


However, this is just a description of the current implementation, not 
an argument that there's no better implementation. Probably there is, 
maybe using the binary package.



Also, the explicit declaration of labels has an inherent safety problem.

[...]

Declaring a label (via f.i.)

 loopStart <- mul exc

at it's instruction doesn't have this problem.


This looks quite elegant, I'll think about it...


If this is what I think it is (tying the knot), then essentially the thunk 
becomes the field reference, backpatching is thunk update, and the Haskell 
environment is the Map.  It should be possible to limit the laziness just to the 
"fields", but I'm not sure if it's possible to "limit the strictness".





Furthermore, having to call 'ensureBufferSize 160' is very strange for
this is data that can be calculated automatically.


As I wrote at haskell-cafe, we require this only for performance 
reasons, to keep buffer overflow checks as seldom as possible. But there 
might be better ways to do this.



I also think that having liftIO in the CodeGen-monad is plain wrong. I
mean, CodeGen is a monad that generates code without any execution
taking place. The execution part is already handled by runCodeGen.
Having liftIO means that arbitrary Haskell programs can be intertwined
with assembly generation and I doubt that you want that.


Feel free to doubt, but this is exactly what we want. :-)

Also, note that runCodeGen runs the code _generation_, executing the 
generated code is done _within_ the CodeGen monad via the functions 
generated by callDecl (or the predefined functions in the Harpy.Call 
module). This is even more intertwined, but intentional.


Of course, again a different design is possible, making runCodeGen 
return a binary code object, that can be called from the IO monad. But 
then, the user has to care about releasing code buffers, and not to have 
unevaluated closures having code pointers to already released run-time 
generated code.


Having this as an option would be very nice I suspect.  I'd like it.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Newbie help with type-classes

2007-05-11 Thread Derek Elkins

Ryan Ingram wrote:

[EMAIL PROTECTED] is better for this type of question.  Follow-up is set 
to it.


Here's a test case for the problem I'm having; I'm using runhaskell from 
ghc v6.6.
 
Problem #1) Without -fallow-undecidable-instances, I get the following 
error:

Constraint is no smaller than the instance head

This is bad.


Problem #2) With -fallow-undecidable-instances, I get this error instead:
Overlapping instances for ConvertToIntList ()


I don't understand why there is an overlapping instances error; () is 
not an instance of ConvertToInt so how could that instance ever apply?


I write anywhere, instance ConvertToInt () where ...
Now it is overlapping.

Is there something basic about type-classes that I'm not understanding 
here?  
They are open (Open World Assumption).  I can add a new instance anywhere at any 
time.



Code below:
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
 
module TestCase

where
 
class ConvertToInt a where

   conv :: a -> Int
 
class ConvertToIntList a where

   convl :: [a] -> [Int]
 
instance ConvertToInt Int where

   conv = id
 
instance ConvertToInt a => ConvertToIntList a where

This is what it's complaining about in the first error; this doesn't work.


   convl = map conv
 
instance ConvertToIntList () where

   convl x = []

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


Re: [Haskell] Re: Newbie: what are the advantages of Haskell?

2007-04-27 Thread Derek Elkins

Albert Y. C. Lai wrote:

Derek Elkins wrote:
And then you come to Haskell and you -can- say, "Give me the something 
that is not there yet."


Please give me the libraries that are not there yet!  *duck*


We wait for people to need the libraries, then a large amount of delayed work is 
forced.

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


Re: [Haskell] Re: Newbie: what are the advantages of Haskell?

2007-04-27 Thread Derek Elkins

Tony Morris wrote:

mike clemow wrote:

Troy,

As a Java chimp embarking on the Haskell journey myself, I'd be
interested in hearing about specific ways that learning Haskell has
changed the way you program Java.  How do you employ the "very
interesting concepts" that you have learned through your study of
Haskell in your Java programming?  Do you employ them at all?  _Can_
they be employed in Java?  Has it made you a better Java programmer?

Cheers,
Mike


I reinvented functional programming when I was using Java rather than
Haskell making me use Java more succintly. I knew something was
seriously wrong with imperative programming and Java's type system all
those years I spent working on the implementation for IBM. I was pleased
to learn that Haskell incorporated many of my ideas (and more) -
validating my original suspicions. The fact that many of the concepts in
Haskell I had already "invented" made the language easy for me to learn
(as in, "oh yeah of course that makes perfect sense" in response to
discover monads).

I produced many Java projects in an attempt to demonstrate what I
thought was wrong, but few of them remain due to loss of interest.

http://jtiger.org/
http://code.google.com/p/pure-functional-java/

In regard to the original question, 'What are the mysterious "side
effects" which are avoided by using Haskell, which everyone talks about?
Null pointers?', my response is "yes".

Looking at a NullPointerException (NPE), these exist because of the
imperative nature of the code; with explicit order of evaluation and
potential side-effects. In an attempt to highlight the absurdity of the
fact that a NPE even exists, I like to tell people that "NPEs occur when
you write a program that says, 'give me the something that is not there
yet'".


[cut]

And then you come to Haskell and you -can- say, "Give me the something that is 
not there yet."


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


Re: [Haskell] Articles on the value of strong typing

2007-03-26 Thread Derek Elkins

Casey Hawthorne wrote:

You may find the following comment interesting.

"The mythos of type systems is that they help the programmer.  But the
reality is compiler and hardware design.  Not simply that a fantasy
type system is harder to implement, but that a restricted language is
easier to implement."

page 189
"Theoretical Introduction to Programming"
Bruce Mills
Springer
2006

I don't know if he bases his conclusions on a study or not.


Is this section about performance?  Otherwise, it makes almost no sense.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] same type multiply implementing a class

2007-03-15 Thread Derek Elkins

Wolfgang Jeltsch wrote:

Am Donnerstag, 15. März 2007 03:23 schrieb Daniel Mahler:

Is there any way for the same type to implement a typeclass multiple ways.


You can wrap the type using newtype, thus creating a new type which can 
implement type class methods differently.


This technique is sometimes known as a typeclass wrapper and is related to 
wrapper types and combines well with phantom types. See 
http://www.haskell.org/hawiki/WrapperTypes

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


Re: [Haskell] Control.Monad.Writer as Python generator

2005-04-15 Thread Derek Elkins
On Fri, 15 Apr 2005 12:03:01 -0400
ChrisK <[EMAIL PROTECTED]> wrote:

> You are correct.  Moand.Cont yield even runs without -O optimizing, 
> just slower:
> 
> Monad.Writer counts 10^9 zeros in 99 seconds (user time)
> Monad.Cont counts 10^8 zero in 35 seconds user time.
> So the writer is 3.5 times faster without '-O'
> 
> With -O
> Monad.Writer counts 10^9 zeros in 105 seconds
> Monad.Cont counts 10^8 zeros in 11 seconds, 10^9 zeros in 110 seconds.
> 
> So with '-O' they are the same speed.  Nice.
> 
> Anyone have an idea why ghci can't garbage collect it?
> Is this an actual bug or an innate quirk of the REPL ?

GHCi does not "compile" with optimizations, without -O the strictness analyzer
isn't run.  The difference is most likely due to strictness analysis.  A well
placed strictness annotation or two should be able to make it work in GHCi as
well.  A similar situation occurs with sum: in GHCi for large inputs it
overflows the stack, but when compiled with -O it works correctly, this is
because sum is defined with foldl and not foldl' in GHC.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] integration of functional and imperative programming concepts

2005-03-04 Thread Derek Elkins
> for my diploma thesis, I need to find information about integration of
> functional and imperative programming concepts.  Could somebody of you
> point me to good websites, papers, etc. about this topic?

You haven't been too specific about what kinds of things you are looking
for.  One thing that you might find useful is,
http://www.mm.informatik.tu-darmstadt.de/~kuehne/fps/.  Also there are
plenty of functional-object-oriented languages.  Checking the paper
listings of FOOL conferences should provide many other papers.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] hs2lhs

2004-02-14 Thread Derek Elkins
On Sat, 14 Feb 2004 15:25:07 -
"Stenio" <[EMAIL PROTECTED]> wrote:

> I need to convert some scripts (hs) to lhs (literate script) and lhs
> (literate script) to hs using GHC. Can someone help me.

GHC comes with an unlit program that will convert lhs to hs files,
there's probably also some flag you can give to GHC to have it spit out
the .hs file after processing it.  As for hs to lhs, there doesn't seem
much point nor is tool support necessary.  You can either add
\begin{code} \end{code} to the beginning and ending of the file
respectively to get a LaTeX style lhs file or one way or another (e.g.
:%s/^/> / in vim) get Bird style lhs files.  You can make such a
program in one line of Haskell,
main = getContents >>= mapM_ (putStrLn . ("> "++)) . lines

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: from array update algorithm to nice Haskell code

2003-12-31 Thread Derek Elkins
> On Tue, 30 Dec 2003 23:14:05 +0100, Wolfgang Jeltsch
> <[EMAIL PROTECTED]> wrote:

[replying indirectly because the original email doesn't seem to have
gotten here yet]

> > I have an algorithm which updates one or more arrays in a loop.  The
> > update operations depend on the (old) contents of the arrays, so I
> > cannot use accumArray.  I want to implement this algorithm without
> > mutable arrays in Haskell.  Are there any possibilities to do so
> > efficiently?  Are there some hints about how to do this?

You may want to look at DiffArrays
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data.Array.Diff.html

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: no continuations

2003-12-30 Thread Derek Elkins
On Tue, 30 Dec 2003 10:38:33 -0800 (PST)
Ben Rudiak-Gould <[EMAIL PROTECTED]> wrote:

> On Tue, 30 Dec 2003, Scott wrote:
> > Why does Haskell have no continuations?
> > (http://www.haskell.org/hawiki/CoMonad)
> > If continuations are incompatible with non-strict semantics, I'd 
> > appreciate an explanation.

> Unrestricted call/cc seems to be incompatible with referential
> transparency in a very fundamental way, and Haskell is nothing without
> referential transparency. On the other hand, it doesn't cause any
> problems when the evaluation order is fixed by some monad, whence
> MonadCont.

Indeed, the simplest example is probably implementing exceptions with
call/cc.

Assuming a callCC function what does the following return,
callCC (\k -> k 1 + k 2)?

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Why are strings linked lists?

2003-12-09 Thread Derek Elkins
On Tue, 09 Dec 2003 10:51:08 +
Graham Klyne <[EMAIL PROTECTED]> wrote:

> At 15:52 08/12/03 -0500, Derek Elkins wrote:
> > > What Haskell byte code projects are out there?
> >
> >The most obvious is the LVM.  See Helium though the LVM is not tied
> >to it.
> 
> I tried to track that down (for a colleague), but the link at:
>http://www.cs.uu.nl/helium/documentation.html
> to:
>http://www.cs.uu.nl/~daan/papers/lvm.pdf
> is broken, and I can't find any other references.

Yeah, it seems to have disappeared off the face of the Internet (quite a
feat).  Emailing Daan Leijen may produce something.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Why are strings linked lists?

2003-12-08 Thread Derek Elkins
On Mon, 8 Dec 2003 20:59:53 +0100
Wolfgang Jeltsch <[EMAIL PROTECTED]> wrote:

> Am Montag, 8. Dezember 2003 15:13 schrieb Tomasz Zielonka:
> > [...]
> 
> > Even in unoptimized, byte-code compiled code?
> 
> Does GHCi use byte code internally? 

Yes.

> What Haskell byte code projects are out there?

The most obvious is the LVM.  See Helium though the LVM is not tied to
it.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pattern-matching extension?

2003-12-08 Thread Derek Elkins
On Mon, 8 Dec 2003 15:37:46 +1100
Fergus Henderson <[EMAIL PROTECTED]> wrote:

> On 05-Dec-2003, Derek Elkins <[EMAIL PROTECTED]> wrote:
> > "Abraham Egnor" <[EMAIL PROTECTED]> wrote:
> > > I've occasionally wanted some sort of equivalent of an instanceOf
> > > function in haskell, i.e. one that would let me define a function
> > > that could dispatch on the type of its argument as well as the
> > > value.  One option I've seen for this is
> > > "http://okmij.org/ftp/Haskell/class-based-dispatch.lhs";, but that
> > > unfortunately has the downside of requiring you to write both a
> > > constructor for PACK and an instance of Packable for each type
> > > you'd like to dispatch on.
> > > 
> > > The thought occurred to me that it is (intuitively) natural to do
> > > this via extending the pattern-matching facility to include types
> > > as well as literal values, i.e. something like:
> > > 
> > > f :: a -> String
> > > f (a :: Int) = "got an int, incremented: "++(show (a+1))
> > > f (a :: Show q => q) = "got a showable: "++(show a)
> > > f _ = "got something else"
> > > 
> > > This has a couple of nice features - it's a simple extension of
> > > the syntax, and acts as a sort of type-safe typecast.  However, I
> > > have zero knowledge of how hard it would be to implement this, and
> > > there may be theoretical difficulties I haven't seen.  Thoughts?
> ...
> > data Showable = forall a. Show a => Showable a
> > 
> > instance Show Showable where
> > show (Showable showable) = show showable
> > 
> > -- extension: pattern guards (I think Hugs has them but I don't
> > think-- NHC does. They are only used for prettiness here.)
> > f :: Dynamic -> String
> > f val | Just (a :: Int) <- fromDynamic val
> > = "got an int, incremented: "++show (a+1)
> >   | Just (a :: Showable) <- fromDynamic val
> > = "got a showable: "++show a
> 
> Casting to a "Showable" is not the same as a dynamic class cast.  

I agree.  In the "..." above, I say "What you could do today".

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pattern-matching extension?

2003-12-05 Thread Derek Elkins
On Wed, 03 Dec 2003 15:10:07 -0500
"Abraham Egnor" <[EMAIL PROTECTED]> wrote:

> I've occasionally wanted some sort of equivalent of an instanceOf
> function in haskell, i.e. one that would let me define a function that
> could dispatch on the type of its argument as well as the value.  One
> option I've seen for this is
> "http://okmij.org/ftp/Haskell/class-based-dispatch.lhs";, but that
> unfortunately has the downside of requiring you to write both a
> constructor for PACK and an instance of Packable for each type you'd
> like to dispatch on.
> 
> The thought occurred to me that it is (intuitively) natural to do this
> via extending the pattern-matching facility to include types as well
> as literal values, i.e. something like:
> 
> f :: a -> String
> f (a :: Int) = "got an int, incremented: "++(show (a+1))
> f (a :: Show q => q) = "got a showable: "++(show a)
> f _ = "got something else"
> 
> This has a couple of nice features - it's a simple extension of the
> syntax, and acts as a sort of type-safe typecast.  However, I have
> zero knowledge of how hard it would be to implement this, and there
> may be theoretical difficulties I haven't seen.  Thoughts?

Dynamics let you do this to some extent and using pattern guards gives
you a reasonable syntax for it.  Clean has syntax like the above for
handling Dynamics and it also supports polymorphic values if I'm not
mistaken.  Dynamics in Haskell as currently implemented are only
monomorphic.  What you could do today is the following... (untested)

{-# OPTIONS -fglasgow-exts #-}
-- you should be able to get something similar in both Hugs and NHC

import Data.Dynamic

-- extension: local existentials (I think NHC only has local universals
-- you can use those to get existentials though.)
data Showable = forall a. Show a => Showable a

instance Show Showable where
show (Showable showable) = show showable

-- extension: pattern guards (I think Hugs has them but I don't think
-- NHC does. They are only used for prettiness here.)
f :: Dynamic -> String
f val | Just (a :: Int) <- fromDynamic val
= "got an int, incremented: "++show (a+1)
  | Just (a :: Showable) <- fromDynamic val
= "got a showable: "++show a
  | otherwise = "got something else"

There are other things you could do, but this seems closest to what you
are looking for.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: How to best add logging/debugging code?

2003-11-27 Thread Derek Elkins
On Thu, 27 Nov 2003 14:19:53 +
Malcolm Wallace <[EMAIL PROTECTED]> wrote:

> > > Is there a list of problems anywhere with using trace?  For 
> > > example does it affect evaluation order?
> 
> Apart from changing the evaluation order of expressions, trace has
> other drawbacks, noted I think by Lennart(?) but I can't remember
> exactly where.  One issue is this:
> 
> Consider an expression where the printable argument to 'trace' causes
> the evaluation of another expression which itself is defined using
> 'trace'.  The nested 'trace' outputs will appear interspersed with
> each other.  In recursive definitions this can become quite painful
> to disentangle.

trace is handy for quick debugging, but if you reach this point, HOOD
would probably be a better choice (or some of the other debugging
technologies, e.g. Buddha, Hat, HsDebug).

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: ANNOUNCE: attribute 0.1

2003-11-13 Thread Derek Elkins
On Thu, 13 Nov 2003 16:06:24 -0500
"Abraham Egnor" <[EMAIL PROTECTED]> wrote:

Sorry that I'm too lazy to download the the tar.bz2 and see for myself,
but...

>   that applies those functions to a monadic reference.  Instances for
>   MRef are provided for both IORef and STRef.

Assuming MRef is like the below, did you include Lazy.ST too?

On a more general note, sticking something like MonadRef somewhere in
the heirarchical libs seems like it would be useful.  Or perhaps Iavor's
monad library?

instance MonadRef IO IORef where
newRef = newIORef
readRef = readIORef
writeRef = writeIORef

instance MonadRef (Lazy.ST s) (STRef s) where
newRef = Lazy.strictToLazyST . newSTRef
readRef = Lazy.strictToLazyST . readSTRef
writeRef = (Lazy.strictToLazyST .) . writeSTRef

instance MonadRef (Strict.ST s) (STRef s) where
newRef = newSTRef
readRef = readSTRef
writeRef = writeSTRef

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: forkIO implemenation

2003-10-16 Thread Derek Elkins
On Thu, 16 Oct 2003 21:31:26 -0400
"Feingold, Jason (WingspanTech)" <[EMAIL PROTECTED]> wrote:

[You may want to set your email program to wrap lines on sending and
send just plain-text.]

> I infer from a discussion from March 2002 that concurrency in Haskell
> is not implemented in native threads, at least in Windows.  Is this
> true? 

Yes, for at least Hugs and GHC, for the most part.

> The reason I ask is that when I forkIO and accept from a socket in the
> new thread everything seems blocked.  Is this the expected behavior? 

Depends on what implementation and version you are using (which you
didn't mention). I assume you are using GHC5, in which case the Windows
socket binding is blocking. This is apparently fixed in GHC6.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: IO behaves oddly if used nested

2003-10-02 Thread Derek Elkins
On Thu, 02 Oct 2003 12:47:15 +0200
Lennart Augustsson <[EMAIL PROTECTED]> wrote:

> Alastair Reid wrote:
> 
> >>Another question with a trivial answer, what is the result of:
> >>
> >>  main :: IO (IO ())
> >>  main = return (putStr "Hello World!")
> > 
> > 
> > It is a computation which, if executed, will print "Hello World"
> > 
> > 
> >>Clearly it also shows the relation between IO and chosen evaluation
> >>strategy.
> > 
> > 
> > This isn't clear to me at all - can you explain further?
> Is it even type correct with
>main :: IO (IO ())
> If it is, it shouldn't be.  It makes no sense.
> The value computed by the top level IO action should
> have some consumer.  Sensible types for the consumer
> (which in some sense is the OS) are () or some exit code.

If I'm not mistaken, the Report restricts main's type to be, at least,
IO a.  Anyways, it's perfectly sensible to return anything.  The RTS
simply discards it. The above example as an entire program is an IO
action that returns an IO action that is discarded by the RTS. I.e. the
program doesn't do anything.  Neither example is odd behavior, unless
you consider Hugs providing a perfectly reasonable instance of Show for
IO a odd.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: learning to love laziness

2003-09-25 Thread Derek Elkins
On Thu, 25 Sep 2003 12:59:37 -0700
Mark Tullsen <[EMAIL PROTECTED]> wrote:

> Haskell has lazy/lifted products and not true products. 

Aren't lazy products true products?  What makes something a product is:
fst (x,y) = x
snd (x,y) = y 
for all x and y.  This holds with lazy products but not eager ones 
fst (3,_|_) = _|_ /= 3

I'd think the problem is that Haskell isn't consistently lazy (for good
reason!).  Haskell has eager coproducts (case analysis).  If you didn't
use pattern matching (or used lazy pattern matching), then this problem
wouldn't come up.  Of course, lazy coproducts (pattern matching) is
somewhat uninteresting (f ~True = 1;f ~False = 2; f False == 1)

> Maybe from seeing this, it's clearer why laws such as
>x = (fst x,snd x)
> do not hold.  Neither does the following law hold
> (uncurry . curry) f = f
> which is unfortunate (for a language named after Haskell *Curry*).
> To see why it doesn't hold, compare t1 and t2 in this program:
>f (_,_) = 1
>t1 = f undefined
>t2 = (uncurry . curry) f undefined

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: How can I implement this arrow? Thanks

2003-09-17 Thread Derek Elkins
On Tue, 16 Sep 2003 23:28:43 -0700
Ashley Yakeley <[EMAIL PROTECTED]> wrote:

> In article <[EMAIL PROTECTED]>,
>  Derek Elkins <[EMAIL PROTECTED]> wrote:
> 
> > > I don't think this type is an arrow. For a "product arrow", i.e.
> > > an instance of Hughes' "Arrow" class with "first" defined, you can
> > > define this:
> > 
> > Oh, it's definitely an arrow.
> 
> I don't think you can make it an instance of Hughes' Arrow without
> some function for combining Strings.

It's not an arrow the way Yu Di wanted it, but it is an arrow.  Which
arrow it is was part of my point in the latter paragraphs.

Here's the StateFunctor from Hughes' paper:
type StateFunctor s a b c = a (b,s) (c,s)

Using String for s and (->) for a we get:
type StringStateArrow b c = (b,String) -> (c,String)

alternatively, looking at the Kleisli arrow with m being the State monad
we get:
type Kleisli m a b = a -> m b
type StateM s a = s -> (a,s)
type StateA s a b = Kleisli (StateM s) a b
type StateA s a b = a -> s -> (b,s)
type StateA s a b = (a,s) -> (b,s)
type StringState a b = (a,String) -> (b,String)

or, if we do combine Strings we get something like the Writer monad:
type Monoid m => WriterM m a = (a,m)
type Monoid m => WriterA m a b = Kleisli (WriteM m) a b
type Monoid m => WriterA m a b = a -> (b,m)
type StringWriterA a b = a -> (b,String)
where mempty = [] and mappend = (++)

In either of these cases, there is not much reason to use an arrow over
a monad if it's the only arrow you are using and there are reasonable
reasons to use a monad over an arrow.  Neither of these do what Yu Di
apparently wanted.  In the more recent post by Yu Di, an arrow or monad
looks more appropriate, though for different reasons and in a different
way, which just goes to show that when posting one should state what
the ultimate goal is.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: How can I implement this arrow? Thanks

2003-09-16 Thread Derek Elkins
On Tue, 16 Sep 2003 14:32:48 -0500
"Yu Di" <[EMAIL PROTECTED]> wrote:

> What I am trying to do is to use Haskell to simulate some process, and
> meanwhile collecting information about the data-flow throughout the
> whole process into the output. The (String, a) example is just a
> simplified version of that. Thanks for pointing out my mistakes, I
> will try to do it as a decorated-data combinator.
> 
> Thanks again,

If all you want to do is trace the execution of some computation, you
can use the Writer/Output monad.  This will associate the outputting
with the functions that process the simulation.  It looks something
like,
foo a b = do
tell ("Entering foo with "++show a++" "++show b)
doStuff a
someMoreStuff b
tell "Leaving foo"

You can write things other than strings.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: How can I implement this arrow? Thanks

2003-09-16 Thread Derek Elkins
On Tue, 16 Sep 2003 01:52:03 -0700
Ashley Yakeley <[EMAIL PROTECTED]> wrote:

> In article <[EMAIL PROTECTED]>,
>  "Yu Di" <[EMAIL PROTECTED]> wrote:

Replying to both:

> > Hi, I want to create an arrow which is essentially
> > 
> > data MyArrow a b = MyArrow ((String, a) -> (String,b))
> 
> I don't think this type is an arrow. For a "product arrow", i.e. an 
> instance of Hughes' "Arrow" class with "first" defined, you can define
> this:

Oh, it's definitely an arrow.

> > i.e. there is an "information" asscioated with each piece of data 
> > (represented by the string), 

So make a data type that sticks together something and it's information.

> > and I want to pass it around. 

What's wrong with the support Haskell already has for passing around
things?  Why do you think you need an arrow?

>From how you read the meaning of the MyArrow type, you are apparently
misunderstanding what arrows are.  Arrows generalize functions. 
As such things of arrow type are intuitively transformers and the arrow
framework standardizes how to stick transformations together to make a
larger transformation. The things in an arrow's representation are
what's required for the implementations of the transformations.
Therefore, things in an arrows representation are, in a sense, "owned"
by the arrow computation. This is evidenced by a) arrows have a fully
polymorphic type, they place no restrictions on their input; within the
computation, the String in MyArrow is not even visible let alone
required to be provided, and b) the above arrow is the State arrow
specialized to Strings. The String is the state and is owned by the
computation. You are having trouble defining 'first' as you'd like
because what you want is to duplicate the state of the
computation. -The- (there is only one at any time) String being passed
around isn't associated with the objects.

>From the sounds of it you simply want a combinator library that operates
on some decorated data.  A monad or arrow may be useful to support
that, e.g. the environment monad, but a monad/arrow isn't that.  You
haven't really given much detail to what you're ultimately trying to
achieve so I can't really provide much advice.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: lexer puzzle

2003-09-13 Thread Derek Elkins
On Sun, 14 Sep 2003 00:30:40 +0200
Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:

> Dnia pi_ 12. wrze_nia 2003 20:31, Iavor Diatchki napisa_:
> 
> > what do people think should be the tokens produced by a haskell
> > lexer when applied to the following input:
> >
> >A...
> 
> A (constructor), then ... (operator).
> This is how I understand Haskell 98 lexing rules.

My first thought was that it should produce, A.. ., as in (.) (A..), but
obviously that would be wrong as A.. must be a function and therefore to
be passed to (.) it would need to be (A..).

So with a little more thought, I seem to agree with GHC despite it being
non-sensical.

GHC produces the following given: 
5 Prelude... 6
"Variable not in scope: `Prelude...'"

I take this to mean the (..) function from the Prelude module.  This is,
as far as I'm concerned, syntactically correct, despite the fact that
there isn't any way to make a (..) function* as .. is syntax (A... being
different syntax).

* Well... actually I'm pretty certain you could with TH

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: container for different types, avoiding boiler plate

2003-08-20 Thread Derek Elkins
On Wed, 20 Aug 2003 08:25:39 -0700
"Hal Daume" <[EMAIL PROTECTED]> wrote:

> I use my 'DynamicMap' type to handle this sort of thing.  However, I
> don't really recommend this approach unless you're very careful.  You
> basically lose out on all nice type checking properties and enter a
> world of dynamic typing (more or less).
> 
> Anyway, you can find it at:
> 
>  http://www.isi.edu/~hdaume/DynamicMap.hs
> 
> it uses "NLP.FiniteMap", but you can replace this with
> "Data.FiniteMap".
> 
> You can then do things like:
> 
>   data Gender = Masc | Fem | Neutr  deriving Typeable
>   data Number = First | Second | Third  deriving Typeable
> 
>   let dm = addToDM (addToDM emptyDM Masc) Second
> 
>   case lookupDM dm of
> Just Masc -> "is a guy"
> Just _-> "is not a guy"
> _ -> "i don't know gender"
> 
>   case lookupDM dm of
> Just First  -> "is first"
> Just Second -> "is second"
> _   -> "either i don't know or is third"
> 
> of course 'deriving Typeable' means you need GHC6; otherwise you can
> write the instances by hand.

One useful thing I've found when using Dynamics is that pattern guards
can be used as a relatively compact typecase.  E.g.

foo dyn | Just b <- fromDynamic dyn = if b then "T" else "F"
| Just (s :: String) <- fromDynamic dyn = show s
| otherwise = show dyn

The only other way I could think of getting typecase like behavior at
another time before I knew about pattern guards was through a horrendous
set of nested case statements.

Another trick for debugging is it is fairly easy to get Haskell to know
the "expected" type, so that you can have error messages, in a generic
error handling routine, like, "expected Int but got <>".

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: help!

2003-08-17 Thread Derek Elkins
On Mon, 18 Aug 2003 10:03:45 +1000
"Trouble ..." <[EMAIL PROTECTED]> wrote:

> Hi!
> 
> I'm new to this whole programming thing, and I was wondering if
> someone can help me out with the following question:
> 
> How do I translate a string into an integer. For example, I need to
> know how to translate "one hundred" into 100, or "fifty thousand  ten
> " into 50 010 etc etc .. I need to know how to do this for single
> numbers, hundreds, thousands and millions using Haskell.

This sounds like homework, nevertheless here's something to get you
started.

You can use the standard function 'words' to turn the string into a list
of words, e.g. words "foo bar baz" ==> ["foo","bar","baz"]

Then you can use some kind of mapping function/data structure (e.g.
FiniteMap, assoc list, a function that pattern matches each possibility)
to map the words to numbers, so you'd have something like,
mappingFunc ["one","hundred"] ==> [1,100]

Then with a little thinking and trial & error an algorithm to combine
those numbers correctly isn't too hard.  Exploring the standard
libraries is helpful for this (or heck in general, there are all kinds
of good things in there).

Beyond this, you'd probably want some error checking, "three three" or
"thirteen million two million" aren't numbers, and it's a simple
exercise in abstracting out repeated patterns to generalize to the
largest multiple you have (i.e. to handle billions, trillions, etc.)

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: HI && TypeCast

2003-08-08 Thread Derek Elkins
On Wed, 6 Aug 2003 23:24:13 +0200
"Fredrik Petersson" <[EMAIL PROTECTED]> wrote:

> Hi there!
> Iam new to the list so feel free to shout at me when i do wrong! :)
> Software-designer from sweden, likes fast bikes and metal, thats me,
> and hi to you all!
> 
> Yeah ok to the problem,
> i have this stupid code,
> [c | (c,i) <- l]
> 
> Where (c,i) are a tuple from a (Char,Int) and l is a [(Char,Int)]
> So far everthings nice but i would like to cast the c to a Sting and
> add : in front,
> So if i fry with a list like [('d',3)('f',3)]
> I end up with
> "fg" but i want it to look like
> ":f :g"

":d :f", ay? ;)

> 
> piece of cake, huh?
> Give me a hit or a webpage to read more from...?

www.haskell.org/learning

> How do you TypeCast in haskell?

You don't.  Anyway's what you want isn't a "typecast" in any language.

concat [[':',c] | (c,i) <- l] 
-- actually this will give you ":f:g"
-- concat (intersperse " " [[':',c] | (c,i) <- l]) will give you ":f :g"
-- I think intersperse is in module List (Data.List) by the way.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: The madness of implicit parameters: cured?

2003-08-03 Thread Derek Elkins
I kinda think someone mentioned this, perhaps even you.  Or maybe I'm
thinking of something else.  As I'm feeling too lazy to check the
archives, at the risk of saying something stupid or repeating something
said, you may want to look at named instances (google should turn
something up with a little effort.)  It seems to cover some of the
same issues/ideas you are having now, though in a different context.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: The madness of implicit parameters: cured?

2003-08-03 Thread Derek Elkins
On Sun, 3 Aug 2003 08:01:52 -0700 (PDT)
Ben Rudiak-Gould <[EMAIL PROTECTED]> wrote:

> On Sat, 2 Aug 2003, Derek Elkins wrote:
> 
> > Ben Rudiak-Gould <[EMAIL PROTECTED]> wrote:
> > 
> > > More recently, I've realized that I really don't understand
> > > implicit parameters at all. They seemed simple enough at first,
> > > but when I look at an expression like
> > > 
> > > f x = let g y = ?foo in g
> > > 
> > > I realize that I have no idea what f's type should be.
> > 
> > Do you have problems finding the type of
> > 
> > f x = let g y = 4 in g
> > ?
> > it works -EXACTLY- the same way.
> 
> No, there is a big difference: There's just one dictionary value for
> each type class instance, and it's global to the whole application. As
> a result, it doesn't matter when hidden dictionary arguments are
> applied. But implicit parameters are scoped, so it matters a lot when
> they're applied. This opens up a big can of worms that the
> type-context system has never had to deal with before.

I wasn't talking about the semantics, I was talking about the
type-inference.

The "Implicit Parameters: dynamic scoping and static typing" makes a
point at least twice that the interpretation of code using implicit
parameters is dependent on the type not just the syntax.

> > Implicit parameters aren't as "flexible" as full dynamic scoping
> > would be.  For example,
> > 
> > f g = let ?foo = 5 in g ()
> > g x = ?foo
> > 
> > f g :: {foo :: a) => a 
> > NOT
> > f g :: Num a => a
> > i.e. it doesn't evaluate to 5.
> 
> But it should. Or rather, either it should evaluate to 5 or it should
> be a compile-time error, because the programmer clearly thought that g
> within the body of f had a implicit parameter ?foo when in fact it
> didn't.

How does g not have an implicit parameter.  It could not but that's not
the issue here.  The issue is the programmer thought that the binding to
?foo would influence g.  Here the type would make it obvious that it
shouldn't.  Whether you want this ability or not in this or the other
example is debatable.

> In my proposal this is a type error; the message would be something
> like"g () does not have an implicit parameter ?foo, in the expression
> 'let?foo = 5 in g ()'". It would be easy to add a helpful message to
> the effect that function arguments can't have implicit parameters
> (which is still true in my proposal).

Would let ?foo = 4 = id be an error then?  or let ?foo = 4 in 4?  There
is no reason to require the body to use an implicit
parameter.

> > > The final straw was:
> > > 
> > > Prelude> let ?x = 1 in let g = ?x in let ?x = 2 in g
> > > 1
> > > Prelude> let ?x = 1 in let g () = ?x in let ?x = 2 in g ()
> > > 2
> > 
> > Compare,
> > 
> > let g = (<) in (g 'a' 'b',g 1 2)
> > 
> > let g x y = x < y in (g 'a' 'b',g 1 2)
> 
> One of your expressions behaves as expected, the other is a type
> error. I'm happy with both of these outcomes. But my expressions both
> typecheck, but then do different things. That's scary. I was burned by
> this once, and now when I try to write code with implicit parameters I
> have to think to myself constantly, "is this going to do what I
> expect? Is this going to do what I expect?". 

Indeed, this is pretty bad, but except for the monomorphism restriction
issue, the behavior doesn't seem any less comprehensible than dynamic
scoping ever is. However, what to expect is pretty obvious when looking
at the type(at least as far as dynamic scoping is obvious.) The
documentation should mention this behavior or implicit parameters should
not suffer the monomorphism restriction and the documentation should
warn against the potential lack of sharing.

> The big selling point of
> functional programming is that it makes programs easy to reason about,
> but implicit parameters (as presently implemented) violate this
> principle to an extent that I've never seen in any other language
> except Perl.

Implicit parameters are meant to implement dynamic scoping.  Dynamic
scoping does typically make programs more difficult to reason about.  I
can only think of a few cases where implicit parameters might be a good
idea.  Perhaps I should see what Ashley Yakeley is doing with them as I
virtually never use them.  I typically use a Reader monad whenever I
want behavior like this.

> > In fact, if you use -fno-monomorphism-restriction, your examples
> > above give you the same numbers.
&g

Re: The madness of implicit parameters: cured?

2003-08-02 Thread Derek Elkins
On Sat, 2 Aug 2003 00:45:07 -0700 (PDT)
Ben Rudiak-Gould <[EMAIL PROTECTED]> wrote:

> When I first learned about implicit parameters I thought they were a
> great idea. The honeymoon ended about the time I wrote some code of
> the form"let ?foo = 123 in expr2", where expr2 used ?foo implicitly,
> and debugging eventually unearthed the fact that ?foo's implicit value
> was not being set to 123 in expr2. That was enough to scare me off of
> using implicit parameters permanently.
> 
> More recently, I've realized that I really don't understand implicit
> parameters at all. They seemed simple enough at first, but when I look
> at an expression like
> 
> f x = let g y = ?foo in g
> 
> I realize that I have no idea what f's type should be. Is it
> 
> (?foo :: c) => a -> b -> c
> 
> or is it
> 
> a -> ((?foo :: c) => b -> c)

Do you have problems finding the type of

f x = let g y = 4 in g
?
it works -EXACTLY- the same way.

> 
> ? As far as I can tell, these are not the same type: you can
> distinguish between them by partially applying f with various
> different values of ?foo in the implicit environment. 

If you do apply f you get (?foo :: c) => b -> c.

GHC tells me
> that f has the former type, but I still have no idea why: is it
> because g has an implicit ?foo parameter and f implicitly applies its
> own ?foo to g before returning it? Why would it do that? Or is it
> because ?foo is here interpreted as referring to an implicit parameter
> bound in the call of f, instead of in g? That doesn't make sense
> either.

The constraint should just be thought of as an extra "explicit"
parameter, or think of it as using the same mechanism dictionary
passing for type classes uses. Implicit parameters aren't
as "flexible" as full dynamic scoping would be.  For example,

f g = let ?foo = 5 in g ()
g x = ?foo

f g :: {foo :: a) => a 
NOT
f g :: Num a => a
i.e. it doesn't evaluate to 5.  So you can't bind the free implicit
variables of a passed in HOF (basically you can't have type ({?foo :: t
=> a -> t) -> b), and similarly you can't return HOF's with free
implicit parameters (no type a -> ({?foo :: t => t -> b))

If I'm not way rusty with CL, here are similar examples with full
dynamic scoping,
> (defvar *x* 0)
*X*
> (defun f (g) (let ((*x* 5)) (funcall g)))
F
> (defun g () *x*)
G
> (f #'g)
5
> (defun f (x) (defun g (y) *x*))
F
> (let ((*x* 1)) (f 'a))
G
> (funcall * 'b)
0
> (let ((*x* 2)) (funcall ** 'b))
2


> The final straw was:
> 
> Prelude> let ?x = 1 in let g = ?x in let ?x = 2 in g
> 1
> Prelude> let ?x = 1 in let g () = ?x in let ?x = 2 in g ()
> 2
> 
> This is insanity. I can't possibly use a language feature which
> behaves in such a non-orthogonal way.

Compare,

let g = (<) in (g 'a' 'b',g 1 2)

let g x y = x < y in (g 'a' 'b',g 1 2)

the problem with this is again -EXACTLY- the same because implicit
parameters behave very much like class constraints, because class
constraints pretty much ARE implicit parameters.  The problem here is
the monomorphism restriction.  This applies to implicit parameters as
well for the same reasons (and because implicit
parameters are very likely handled by the same code.)  In fact, if you
use -fno-monomorphism-restriction, your examples above give you the same
numbers.
   ___ ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |  GHC Interactive, version 5.04.3
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base ... linking ... done.
Loading package haskell98 ... linking ... done.
Prelude> :set -fglasgow-exts
Prelude> let ?x = 1 in let g = ?x in let ?x = 2 in g
1
Prelude> let ?x = 1 in let g () = ?x in let ?x = 2 in g ()
2
Prelude> :set -fno-monomorphism-restriction
Prelude> let ?x = 1 in let g = ?x in let ?x = 2 in g
2
Prelude> let ?x = 1 in let g () = ?x in let ?x = 2 in g ()
2

Whether your additions would be worthwhile anyways, I haven't really
thought about.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: a breaking monad

2003-08-01 Thread Derek Elkins
On Fri, 1 Aug 2003 12:02:00 +0200
Tomasz Zielonka <[EMAIL PROTECTED]> wrote:

> On Thu, Jul 31, 2003 at 05:15:33PM -0400, Derek Elkins wrote:
> > On Thu, 31 Jul 2003 13:18:40 -0700
> > "Hal Daume" <[EMAIL PROTECTED]> wrote:
> > 
> > > so, my questions are: does this exist in some other form I'm not
> > > aware of?  is there something fundamentally broken about this
> > > (sorry for the pun)?  any other comments, suggestions?
> > 
> > This looks like a bizarre rendition of the Error/Exception monad.
> > 
> > I believe the function "breakable" would be fairly accurately
> > represented with '\b -> runErrorT b >>= either return return' and
> > use throwError for break.
> 
> I used the Cont(inuation) monad for similar purposes. This has an
> advantage that you can choose a place to break (jump?) into, each
> place having a possibly different type of return value.

I was thinking of providing a Cont example too.

> PS. Are there other uses of Cont monad?

I've used it for resumptions, and I imagine you could use it to handle
the CP in an "optimized" via CPS function, though that likely isn't
worthwhile (heh).  Hinze's Backtracking monad uses CPS but not the Cont
monad, though it may be representable with ContT over Cont, I'm pretty
sure shift/reset can get the same effect.

Less immediately practical, I've experimented with shift/reset with it.
I'm kind of interested in translating Filinsky's monadic reification and
reflection into Haskell with the Cont(T) monad.  This would probably
have no real practical benefit (or would it... run-time changing?), I
believe a similar effect usage-wise can be achieved by using a class for
the monad parameter (MonadState/etc.) It would be more practical if a
compiler internally supported a Cont(T) monad.

Anyways, most of my uses of the Cont monad have been for my own personal
entertainment, and usually I break the abstraction (using
Control.Monad.Cont) to do the things I want.  I don't know if I've ever
written something that's used callCC that I kept.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Use of H98 FFI

2003-08-01 Thread Derek Elkins
On 01 Aug 2003 09:44:14 +0200
Peter Thiemann <[EMAIL PROTECTED]> wrote:

> I recently had my first exposure to Haskell's FFI when I was trying to
> compute MD5 and SHA1 hashes using the existing C implementations. In
> each case, the idea is to make the hash function available as function
> 
> > md5 :: String -> String
> 
> However, the naive implementation
> 
> > md5_init md5_state
> > n <- newCString str
> > md5_append md5_state n (fromIntegral (length str))
> > md5_finish md5_state md5_digest
> 
> does not scale to computing hashes of really long strings (50 MB, say,
> as arising from reading a moderately big file), since it tries to
> create a CString of that size, first! 
> 
> Trying to avoid the allocation of this giant CString requires to split
> up the original string into smaller parts and convert each part to a
> CString separately. Clearly, this task involves a lot of allocation,
> essentially the input string needs to be copied part by part.
> 
> Hence, I was wondering why the FFI only provides functionality to
> convert an *entire* list of Char into a CString. For applications like
> this hash computation, it would be advantageous to be able to specify
> *how much* of the input string to marshall to the CString and have the
> conversion function return the rest of the input string and the
> CString. That is, in addition to 
> 
> > newCString :: String -> IO CString
> 
> there should be
> 
> > newCStringPart :: String -> Int -> IO (CStringLen, String)
> 
> or even
> 
> > toCStringPart :: String -> CStringLen -> IO (Int, String)
> 
> where CStringLen describes a target buffer into which the String
> argument is to be marshalled.  (and similarly for other list types)
> 
> Clearly, I can program this functionality by hand. But I have to
> revert to byte-wise processing using pokeByteOff, castCharToCChar, and
> so on. In addition, the optimizer does not seem to be very effective
> on such code, so it seems advantageous to provide it in the library
> already.
> 
> But perhaps I'm overlooking something, so I'm appending the code I was
> using below.
> 
> -Peter

Except that I would probably mapM_ over a list of chunks, I don't
see what the problem is with your second version of the code is.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: *safe* coerce, for regular and existential types

2003-07-31 Thread Derek Elkins
Throughout this message you imply, if not outright state, that Dynamics
requires unsafeCoerce/unsafePerformIO.  This is simply not the case. 
GHC implements Dynamics with unsafeCoerce, or did last time I checked,
but it can easily be implemented using only existentials. (I presume
that this decision was made either for efficiency, simplicity, and/or
simply that another (readily useable) technique was not known when the
library was made.)

Anyways, as I have often mentioned, "A Lightweight Implementation of
Generics and Dynamics" has an unsafePerformIO/Coerce free implementation
of Dynamics as well as Generics as the title suggests.


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: a breaking monad

2003-07-31 Thread Derek Elkins
On Thu, 31 Jul 2003 13:18:40 -0700
"Hal Daume" <[EMAIL PROTECTED]> wrote:

> so, my questions are: does this exist in some other form I'm not aware
> of?  is there something fundamentally broken about this (sorry for the
> pun)?  any other comments, suggestions?

This looks like a bizarre rendition of the Error/Exception monad.

I believe the function "breakable" would be fairly accurately
represented with '\b -> runErrorT b >>= either return return' and use
throwError for break.

Also, your motivating example is ambiguous.  I think you mainly care
about the case where the test is testing for some "exceptional"
condition.  I personally wouldn't want to use this style every place I
would use an if.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: How to use functions in dll file in Haskell program?

2003-07-18 Thread Derek Elkins
On Fri, 18 Jul 2003 18:29:35 +0800
"Liu Junfeng" <[EMAIL PROTECTED]> wrote:

> Hi__
> If there is a function named "func" with type a->b in a win32 dll
> file. In Hugs use the primitive declaration:
> ---
> primitive prim_func :: a -> b  
> func = prim_func
> ---
> Then the func can be exported to be used in other modules.
> 
> The question is how to do it in GHC?

There's now an effectively standard FFI mechanism that you should be
using for any implementation.  According to the FFI page, Hugs conforms
to the standard, so you should be using it in Hugs as well.

http://www.cse.unsw.edu.au/~chak/haskell/ffi/

As far as DLLs go it's certainly possible to do with GHC.  Read the FFI
addendum and perhaps search this mailinglist for some details.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: literal default value for an unknown type

2003-07-08 Thread Derek Elkins
On Tue, 8 Jul 2003 23:16:33 -0300
"Andre W B Furtado" <[EMAIL PROTECTED]> wrote:

> Is it possible replace the question mark in the following code in
> order to make defaultMyType return a "don't care" value for b?
> 
> data MyType t = MyType { a :: Int, b :: t}
> 
> defaultMyType :: MyType
> defaultMyType = MyType {a = 0, b = ?}
> 

First you do need the type parameter (:: MyType t).

Then you have (at least) three options.

You can replace the ? with undefined.  You can omit b altogether in the
record construction and get the same effect as the first option, or you
could have b :: Maybe t and have the ? be Nothing.  Which (of the
really two options) is best depends on how you intend to use the record.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: let (d,k) = (g x y, h x d) ..

2003-06-27 Thread Derek Elkins
On Fri, 27 Jun 2003 12:22:46 +0400
"Serge D. Mechveliani" <[EMAIL PROTECTED]> wrote:

> Dear Haskellers,
> 
> Once I wrote a function 
> 
>   f' :: Int -> Int -> Int -> (Int, Int)
> 
>   f' n m l = let (d,k) = (gcd n m, quot n d)  in  (k, l*k)
> 
> (the simplified version of real program),
> placing erroneousely  d  to both parts of the pattern matching 
> (d,k) = ...
> 
> The intended program was
> 
>   f  n m l = let {d = gcd n m;  k = quot n d} in  (k, l*k)
> 
> But f' gives the intended results, at least in the GHC 
> implementation. 
> So that I did not notice the `error' for a long time.
> 
> Is really the Haskell pattern matching semantic so that f and f' 
> are equivalent ?

Haskell is a lazy language.  You can define values in terms of
themselves (with emphasis on -values-).

Here's a (relatively) simple example of doing this for more and (some)
explanation see http://haskell.org/hawiki/TyingTheKnot.

-- list_rep_min: replace list with it's minimum value in one pass
list_rep_min l = result
where (result,mini) = lrm l mini
  lrm [x] m = ([m],x)
  lrm (x:xs) m = (m:ms,x `min` m')
where (ms,m') = lrm xs m

> Is it an occasional implementation feature that hide the `error'?

No.  It's a language feature, though it does cause problems.  My advice
is simply to avoid shadowing (local) variables.  I am usually pretty
good about following it, but one particular time I didn't, I ended up
with a function that seemed 'mysteriously' broken.  I felt pretty stupid
when I finally noticed what it was.  Oddly, enough I was actually
thinking that I was shadowing too much as I wrote the code.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: In search of: [a->b] -> a -> [b]

2003-06-20 Thread Derek Elkins
On Thu, 19 Jun 2003 18:05:11 +0200
Christian Sievers <[EMAIL PROTECTED]> wrote:

> Derek Elkins wrote:
> 
> > >  flist :: [a->b] -> a -> [b]
> > >  flist fs a = map (flip ($) a) fs
> > or much nicer (IMO) 
> >   flist fs a = map ($ a) fs 
> 
> This is a case where I'd prefer a list comprehension:
> 
> flist fs a = [ f a | f <- fs ]
> 
> (and this could be a monad comprehension, if Haskell still had
> them...)

I don't think Haskell ever had them (I'd have to check).
Gofer did. Anyways, do-notation is about as expressive as monad
comprehensions. With do-notation you have to add guards explicitly, but
you don't have to end with a return and you don't need to bind
variables, e.g. I believe [() | _ <- putStrLn "foo"] would be necessary
(well, not in this case, but the general one).

> > the generalized solution being simply,
> > f mf x = do
> > f <- mf
> > return (f x)
> 
> Or just replace map by fmap in your flist from above.

That generalizes it, but in a different way since (in Haskell) Monad
isn't a subclass of Functor...

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: In search of: [a->b] -> a -> [b]

2003-06-17 Thread Derek Elkins
On Tue, 17 Jun 2003 21:01:57 +0100
Graham Klyne <[EMAIL PROTECTED]> wrote:

> I'm convinced I've seen a function like this somewhere:
>[a->b] -> a -> [b]
> but cannot remember where.  Or maybe:
>Monad m => m (a->b) -> a -> m b
> ?
> 
> I could roll my own (*), but I'm trying not to duplicate standard
> library functions is I can help it.  Any pointers?

The closest function I see is ap :: Monad m => m (a -> b) -> m a -> m b
(so you could write your function as f fs a = ap fs (return a) not that
I would recommend it).  Also you may want to check out the Haskell
reference at zvon.org, it's indexed by type as well.

 
> #g
> --
> 
> (*)
> 
>  flist :: [a->b] -> a -> [b]
>  flist fs a = map (flip ($) a) fs
or much nicer (IMO) 
  flist fs a = map ($ a) fs 
or breakin' out the point-free style, 
  flist = flip (map . flip ($)) -- okay, so I wouldn't recommend this

the generalized solution being simply,
f mf x = do
f <- mf
return (f x)

ap is almost certainly liftM2 ($) or equivalently,
ap mf mx = do
f <- mf
x <- mx
return (f x)
 
>  flist [(1*),(2*),(3*)] 5 -- = [5,10,15]

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: C++ class structure mapping

2003-06-17 Thread Derek Elkins
On Tue, 17 Jun 2003 09:07:06 +0100
Alastair Reid <[EMAIL PROTECTED]> wrote:

> On Tuesday 17 June 2003 2:33 am, Abraham Egnor wrote:
> > I'd like to make a haskell binding for a C++ library.  Most of the
> > tools out there seem oriented towards c bindings, so it looks like
> > I'll be writing the FFI code generator myself.  While I'm at it I
> > figure I might as well just make a general C++ binding tool.  I've
> > been thinking about this, and I'd like some feedback on the ideas
> > I've had.
> 
> All previous interfaces to C++ libraries that I know of have been
> created by writing a bunch of wrapper functions with C-style types
> like these wrapper for a virtual function 'foo'.
> 
>   void foo_T(S x) { x->foo(); }
>   void foo_T(T x) { x->foo(); }
>   void foo_T(U x) { x->foo(); }
> 
> [Note that these are C++ functions but that their type is one that C
> programs can call.]

I'm assuming you don't want overloading here as these aren't functions
that can be called in C (or C99?).

> 
> People have shied away from trying to create a more direct interface
> because:
> 
> 1) C++ is a huge language (with the complexity mostly in types, 
> classes and templates where you can't easily avoid them) and it seems
> that to be able to cope with any reasonable number of C++ libraries,
> you'd have to implement a large part of that language.
> 
> 2) C++'s type/ class system is quite different from Haskell's class
> system.  Any mapping of on to the other is likely to fall apart rather
> quickly. 

If the code you are interfacing to doesn't make too much use of
templates then you can do what I did and hack together a SWIG module to
flatten the C++ to C (I had hoped that that would already be available
as it effectively does that anyways but I couldn't find it). 

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Stupid wuestion about Monads :)

2003-06-11 Thread Derek Elkins
On Wed, 11 Jun 2003 20:00:00 +0200
Filip <[EMAIL PROTECTED]> wrote:

> I have a question :)
> What should I do if I have something like "IO Bool" and I need "Bool"
> ??

Read the "Gentle Introduction"
http://www.haskell.org/tutorial/

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Typesafe MRef with a regular monad

2003-06-11 Thread Derek Elkins
On Wed, 11 Jun 2003 09:19:46 +0200 (MET DST)
Koen Claessen <[EMAIL PROTECTED]> wrote:

> Derek Elkins wrote:
> 
>  | The question (at least to me) is more, 'you can
>  | satisfy the RefMonad interface with STRefs or IORefs,
>  | but those use "imperative" features under the hood;
>  | can it be satisfied without them?'
> 
> As I showed in the message that spawned off this discussion,
> this is indeed possible to do (unless you think any monad by
> itself is an imperative thing). The only thing one needs to
> focus on is the typing and not the imperativeness.
> 
> /Koen.

Hence the very next sentence,
"Personally, I think Tim Sweeney is
focusing on the wrong aspect.  The problem here has nothing to do with
monads, it's purely a typing issue,"

and the last sentence,

"[...]STRefs/IORefs are only
type safe because they are in a monad, or perhaps you can look at it
another way and they aren't safe at all but monads simply make it
impossible to abuse them, in which case unsafeCoerce is likely the
minimal extension, again this just shows that this is purely a type
issue, unsafeCoerce has nothing to do with monads and I don't think most
would consider it an imperative feature (though a common feature in
imperative languages ;)."

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Typesafe MRef with a regular monad

2003-06-10 Thread Derek Elkins
On Tue, 10 Jun 2003 11:44:45 -0700 (PDT)
[EMAIL PROTECTED] wrote:

> 
> > update  :: (Typable b) => FM k -> Key k a -> b -> (FM ...)
> 
> I didn't know constraints on values are allowed... Given below is the
> implementation of the required interface, in Haskell98

They aren't presumably as that would (as you and another have shown)
make the implementation more or less trivial.  With constraints
you can have a type a -> b (the type of unsafeCoerce) only it's
meaningful and safe as the values are constrained (as opposed to saying
'give me anything and I'll give you whatever you want')  The question
(at least to me) is more, 'you can satisfy the RefMonad interface with
STRefs or IORefs, but those use "imperative" features under the hood;
can it be satisfied without them?'  Personally, I think Tim Sweeney is
focusing on the wrong aspect.  The problem here has nothing to do with
monads, it's purely a typing issue, you can have monads in Scheme and
you could definitely satisfy that interface (in the pure subset) as
implicitly everything is in class Typeable.  Simon PJ pointed this out
best by changing the question to how to make a "polymorphic" finite map.
 That's not to say that arrows, comonads, or monads, or something else
don't have a place (they might not though) as STRefs/IORefs are only
type safe because they are in a monad, or perhaps you can look at it
another way and they aren't safe at all but monads simply make it
impossible to abuse them, in which case unsafeCoerce is likely the
minimal extension, again this just shows that this is purely a type
issue, unsafeCoerce has nothing to do with monads and I don't think most
would consider it an imperative feature (though a common feature in
imperative languages ;).

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Typesafe MRef with a regular monad

2003-06-05 Thread Derek Elkins
On Wed, 04 Jun 2003 15:19:53 -0700
Ashley Yakeley <[EMAIL PROTECTED]> wrote:

> In article <[EMAIL PROTECTED]>,
>  [EMAIL PROTECTED] wrote:
> 
> > Ashley Yakeley wrote:
> > ] ] Is it possible to actually implement a working instance of
> > RefMonad in ] ] Haskell, without making use of a built-in monad like
> > IO or ST?  
> > 
> > ] You certainly wouldn't be able to do this for any monad M which
> > had:
> > 
> > ]   performM :: forall a. M a -> a;
> > 
> > ] ...because it wouldn't be type-safe: you'd be able to construct
> > coerce ] :: a -> b just as you can with unsafePerformIO.
> >  
> > Fortunately, that doesn't seem to be the case.
> 
> That's only because you've failed to do the difficult part: implement 
> newRef. Your monadic solution has a statically typed/sized store: I'd 
> say it doesn't properly count as a "heap" since you can't heap new
> stuff on it.

I agree, if I knew I'd have 5 components before I could just use a 5
tuple and a State monad.  I'd have to look back over the other heap
stuff to see what it provides type-wise, but (at least the "new" monad
version) seems to miss the point.

> The original problem was to create an instance of 
> 
>   class Monad m => RefMonad m r | m -> r where
>  newRef :: a -> m (r a)
>  readRef :: r a -> m a
>  writeRef :: r a -> a -> m ()
> 
> without making use of IO or ST. Given some M and R that have
> 
>   instance RefMonad M R
>   performM :: forall a. M a -> a

M = (forall s.ST s)
R = STRef s

e.g. runST :: (forall s.ST s a) -> a

you can use the same trick for your own RefMonad.  I'm not sure if this
will work with RefMonad exactly.  If ST/STRef can be made an instance of
RefMonad without any trouble though, then I believe it should work.

> one can write this:
> 
>   coerce :: forall a b. a -> b;
>   coerce a = let
> {
> ref = performM (newRef Nothing);
> } in performM (do
> {
> writeRef ref (Just a);
> mb <- readRef ref;
> case mb of {Just b -> return b;};
> });

I was having fun with
coerce :: a -> b
coerce x = unsafePerformIO (writeIORef ref x >> readIORef ref)
where ref = unsafePerformIO (newIORef undefined)

last night, some fun examples (using GHCi 5.04.3),
data Foo a = Bar | Baz a (Foo a)

coerce 5 :: Maybe Int ==> Nothing
coerce 'a' :: Int ==> 97
coerce [1..3] :: Foo Integer ==> (Baz 1 (Baz 2 (Baz 3 Bar)))
coerce [4] :: Maybe Integer ==> Just 4

I need to reread the GHC internals paper, I want to see if I can get one
like
(coerce something :: (sometype -> someothertype)) someotherthing

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Implementing RefMonads in Haskell without ST,IO

2003-05-30 Thread Derek Elkins
On Fri, 30 May 2003 00:00:26 -0500
"Tim Sweeney" <[EMAIL PROTECTED]> wrote:

> Hi Derek,
> 
> How can one implement RefMonad below directly in Haskell?
> 
> class Monad m => RefMonad m r | m -> r where
> newRef :: a -> m (r a)
> readRef :: r a -> m a
> writeRef :: r a -> a -> m ()
> 
> I've been able to implement a monad that encapsulates "references to
> integers", by creating a monad that passes "the heap" (a function
> int->int, from heap indices to integer values stored in the heap) in
> and out of functions.  That was pretty straightforward, and the monad
> makes everything look like an imperative language that supports
> updatable references to integers (and only integers).
> 
> But how can one implement RefMonad to support references of all
> possible types simultaneously?

There isn't without an unsafe coerce function.  However, you can get all
the types that are an instances of a class, e.g. Typeable.  As Hal Daume
said, you can use Dynamics.  GHC's implementation does use an
unsafeCoerce function but "A Lightweight Implementation of Generics and
Dynamics" (or something very close to that) shows that such a function
is unnecessary and only existential quantification is needed to make
Dynamics.  If you want to be able to change the type you store in/at a
reference then this is your only real option.  However, likely you want
typed references.  Dynamics seems unnecessary/overkill for this (though
it may be). You know what type you want, you aren't going to mistake it,
so you shouldn't need to carry around a TypeRep.

Anyways, you may want to check out "A Lightweight Implementation...", it
has some interesting type stuff that may give you ideas.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Implementing RefMonads in Haskell without ST,IO

2003-05-30 Thread Derek Elkins
On Thu, 29 May 2003 22:48:05 -0500
"Tim Sweeney" <[EMAIL PROTECTED]> wrote:

> If it's not possible to implement a typesafe RefMonad instance
> directly in Haskell, without making use of built-in imperative
> features like IO, then doesn't this refute the claims that monads
> implement imperative features functionally?
> 
> -Tim

You certainly can have an instance of RefMonad that -simulates-
updateable references. You can't implement this with update inplace
without an update inplace primitive and if Haskell had an update inplace
primitive that you could use anywhere it wouldn't be a pure language. 
Monads in Haskell -allow- imperative features and use of imperative
features without breaking the purity of the entire language.  Outside a
monadic computation equational reasoning always holds, even when talking
about imperative actions. That monads implement an imperative effect
doesn't mean they implement it the same way an imperative language
would.  Of course, the actual implementation doesn't matter so
implementing it imperatively is just as good as implementing it
functionally as far as static semantics go, which is why everything
(IO&ST) works out.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell