Re: [Haskell-cafe] Rigid skolem type variable escaping scope

2012-08-22 Thread Lauri Alanko

Quoting Matthew Steele mdste...@alum.mit.edu:


{-# LANGUAGE Rank2Types #-}

class FooClass a where ...

foo :: (forall a. (FooClass a) = a - Int) - Bool
foo fn = ...



newtype IntFn a = IntFn (a - Int)

bar :: (forall a. (FooClass a) = IntFn a) - Bool
bar (IntFn fn) = foo fn


In case you hadn't yet discovered it, the solution here is to unpack  
the IntFn a bit later in a context where the required type argument is  
known:


bar ifn = foo (case ifn of IntFn fn - fn)

Hope this helps.


Lauri



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


Re: [Haskell-cafe] Rigid skolem type variable escaping scope

2012-08-22 Thread Lauri Alanko

Quoting Matthew Steele mdste...@alum.mit.edu:

1) bar ifn = case ifn of IntFn fn - foo fn
2) bar ifn = foo (case ifn of IntFn fn - fn)


I can't help feeling like maybe I am missing some small but  
important piece from my mental model of how rank-2 types work.


As SPJ suggested, translation to System F with explicit type  
applications makes the issue clearer:


1) bar = \(ifn :: forall a. IntFn a).
 case ifn _a of IntFn (fn :: _a - Int) - foo (/\a. ???)
2) bar = \(ifn :: forall a. IntFn a).
 foo (/\a. case ifn a of IntFn (fn :: a - Int) - fn)


Lauri



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


RE: ANNOUNCE: GHC 7.4.1 Release Candidate 1

2011-12-28 Thread Lauri Alanko

Quoting Wolfgang Jeltsch g9ks1...@acme.softbase.org:


Am Mittwoch, den 28.12.2011, 12:48 + schrieb Simon Peyton-Jones:

Only that BOX is a sort (currently the one and only sort), whereas
Constraint is a kind.  I'm not sure that BOX should ever be displayed
to users.


Okay, this makes sense then. However, note that the GHC User’s manual
mixes the terminology (“kind” vs. “sort”) at one point:

Note that List, for instance, does not get kind BOX - BOX, because
we do not further classify kinds; all kinds have sort BOX.



I think, it should say “sort BOX - BOX”.


I don't think that would be quite correct. Sorts are typically  
constants, and there are usually a finite amount of them, each  
presenting a level of the type system. For instance, * and BOX are  
both sorts, even though we also have * :: BOX. In a system where BOX  
- BOX would be well-formed, it should probably be called something  
else, maybe kind-classifying term (whose sort would be something  
new, maybe TRIANGLE).


But it seems a bit funny to spend a lot of time thinking about what to  
call things that don't exist in GHC. Maybe it'd be easiest to just  
drop that awkward hypothetical BOX - BOX altogether from the manual.



Lauri


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


Re: [Haskell-cafe] Type trickery

2011-03-16 Thread Lauri Alanko
On Wed, Mar 16, 2011 at 12:05:56PM +, Andrew Coppin wrote:
 withContainer ∷ (∀ s. Container s → α) → α

 Hmm, yes. That will work, but I wonder if there's some way of doing
 this that doesn't limit the scope of the container to one single
 span of code...

You can just pack the container into an existential and pass that
around freely. Only the use of cursors is limited into a scope where
the owning container's type variable is visible (which you get by
unpacking the existential).


Lauri

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


Re: [Haskell-cafe] Splittable random numbers

2011-01-22 Thread Lauri Alanko
On Sat, Jan 22, 2011 at 12:40:04AM -0500, Ryan Newton wrote:
 On Wed, Nov 10, 2010 at 11:33 AM, Lauri Alanko l...@iki.fi wrote:
  So a naive implementation of split would be:
 
  split g = (mkGen seed, g')
   where (seed, g') = random g
 
 Just to be clear, that is the same as Burton Smith's original proposal that
 Simon mentioned at the outset, right?  Specifically, Smith's proposal is
 yours instantiated with a crypto based PRNG?

Yes, I realized this in hindsight. I hadn't read Smith's proposal
fully and didn't expect it to be so simple.

My own interest in this discussion actually came from an OCaml
project, where I needed an operation to generate new RNGs:

val split : Random.State.t - Random.State.t

The obvious idea was just to create a new RNG by using a randomly
generated seed:

let split s =
  Random.State.make (Array.init 55 (fun _ - Random.State.bits s))

However, I remembered years ago reading in the source of the Haskell
Random module that splitting RNGs robustly is supposed to be an open
problem so I wondered what the issue is. Since random numbers came up
on the Haskell mailing list at the same time, I decided to ask. But
since Burton apparently came up with the same solution, using AES in
counter mode as the RNG, maybe there is no issue after all. Except
perhaps performance? Is this approach less robust with a faster,
non-cryptographic RNG?

 So, except for the silliness of generating 128 random bits to make an Int,
 the following would implement the strategy using the crypto package on
 Hackage, correct?

 next128 (RNG k c) = (encrypt k c, RNG k (c+1))

To my understandind that's indeed using AES in counter mode, but I'm
no crypto expert.


Lauri

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


Re: [Haskell-cafe] Lambda Calculus: Bound and Free formal definitions

2010-12-30 Thread Lauri Alanko
On Thu, Dec 30, 2010 at 02:20:34PM +1030, Mark Spezzano wrote:
 5.3 BOUND:
 =
 If E1 = \x.xy then x is bound
 If E2 = \z.z then is not even mentioned
 
 So E = E1 E2 = (\x.xy)(\z.z) = (\z.z)y -- Error: x is not bound but
 should be by the rule of 5.3

Your final = here is beta equality. Were expecting the bound
property to be preserved by beta? As you observed, it is not true. Did
the book claim otherwise?

As for the correctness of the actual definitions
http://books.google.com/books?id=OPFoJZeI8MECpg=PA84, 5.2. seems
correct although sloppily named (it should say X occurs free in E or
X has a free occurrence in E instead of X is free in). 5.3. seems
to define a property that would properly be named there is a binder
for X in E. Note that this is different from e.g. X has a bound
occurrence in E.


Lauri

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


[Haskell-cafe] Formatting function types

2010-12-30 Thread Lauri Alanko
On Thu, Dec 30, 2010 at 07:04:11AM -0600, Larry Evans wrote:
 On 12/29/10 22:40, Daryoush Mehrtash wrote:
  Why do people  put  ; in do {}, or , in data fields,  at the 
  beginning of the line? 
  -- 
 It reflects the parse tree better by putting the
 combining operators (e.g. ';' and ',') at the left
 and their operands (or combined subtrees) indented
 to the right.

I will take this opportunity to mention again a related pet peeve of
mine that I originally griped about ages ago:

http://www.mail-archive.com/haskell-cafe@haskell.org/msg02231.html

Even nowadays, Haddock deliberately generates the following layout for
long function types:

openTempFile
:: FilePath
- String
- IO (FilePath, Handle)

The layout draws special attention to the first argument type, whereas
the other argument types are indistinguishable from the return
type. The following is much clearer:

openTempFile :: 
FilePath -
String -
IO (FilePath, Handle)

(Possibly with the arrows aligned.)

I can't understand how the arrows first convention still lingers so
strongly when it is (to me) so obviously wrong and misleading. Please,
folks, at least pay a thought to what different indentation and line
continuation styles express before adopting one.


Lauri

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


Re: [Haskell-cafe] Formatting function types

2010-12-30 Thread Lauri Alanko
On Thu, Dec 30, 2010 at 10:39:29AM -0600, Larry Evans wrote:
 Lauri, I assume then that you want to draw special attention to
 the return type instead of the first argument type.

Only to the fact that the return type is of a different nature than
the argument types, and that all the argument types are of the same
nature. (More technically, the argument types occur in negative
positions within the function type, whereas the return type occurs in
a positive position.)

 So, with this operator postfix formatting, the special
 attention to the return type is achieved by *not* suffixing it
 with -.

Partly, but more by the fact that it is the last item in the list. Of
course there are ways to make it even more prominent, e.g. by
inserting an empty line before it. The arrows are not really essential
for readability, although they can help a bit if they are aligned:

openTempFile ::
FilePath -
String   -
IO (FilePath, Handle)

 OK, but then why not just find the last argument and forget about
 finding the missing postfix -?  Well, in that case, the operator
 prefix formatting would serve just as well.

Except that it falsely suggests that the last argument types are of a
similar nature as the return type. Here's what went in my head when I
first read Haskell code:

openTempFile ::
   FilePath -- All right, this first part is probably the argument.
- String -- this comes after the arrow, so this must be the return type.
- IO (FilePath, Handle) -- And then we have another return type? Huh?

It took me quite a while to understand that - associates to the
right, because the layout so strongly suggested otherwise. Obviously,
with time one can get used to anything, but I still stand by my
opinion that the above convention is inherently misleading.

 [1]:
   openTempFile
  :: FilePath -- ^ filename, of course
  - String -- ^ comment for 2nd arg.
  - IO (FilePath, Handle) -- ^ comment for 3ird arg

3rd arg? This is just the sort of lapse that the above syntax induces.

 [2]:
   openTempFile::
  FilePath {- ^ filename, of course -} -
  String {- ^ comment for 2nd arg. -} -
  IO (FilePath, Handle) -- ^ comment for 3ird arg

This is admittedly ugly. I'd prefer:

openTempFile ::
FilePath --- ^ foo
String -  -- ^ bar
IO (FilePath, Handle)  -- ^ baz

If Haddock doesn't support an intervening - between the type and the
documentation comment, it probably should.

(Personally, I don't like end-of-line comments because they quickly run
out of space and extending them to multiple lines is awkward. So maybe
even better would be:

openTempFile ::
FilePath -
-- ^ foo
String -
-- ^ bar
IO (FilePath, Handle)
-- ^ baz

But this is no longer relevant to the issue at hand.)


Lauri

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


Re: [Haskell-cafe] Do we need Monad fail (or MonadFail)?

2010-12-21 Thread Lauri Alanko
On Tue, Dec 21, 2010 at 08:31:08AM -0700, Jonathan Geddes wrote:
 I'd love for the compiler to give an error (or maybe just a warning)
 in the case that I have a pattern match in a monad that just blows up
 (throws an exception) on a pattern match failure.

You will be interested to know that everything you ask for already was
in Haskell ages ago:

http://www.cs.auckland.ac.nz/references/haskell/haskell-report-1.4-html/exps.html#do-expressions

They decided to get rid of it in Haskell 98, for reasons that someone
else can probably explain.


Lauri

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


Re: [Haskell-cafe] Type Directed Name Resolution

2010-11-11 Thread Lauri Alanko
On Thu, Nov 11, 2010 at 07:04:16PM +1030, John Lask wrote:
 it is often desirable to have the same field names
 for many records in the same module.

 very much so, this is currently possible, with the restriction that
 the field names must have the same type modulo the record it is
 selecting on.
 
 what is disirable is that this restriction be lifted.

Why on earth? I thought that the motivation for this feature was
simply to deal with naming conflicts with _unrelated_ records from
_unrelated_ modules without having to resort to qualified names. But I
can't see why someone would use the same accessor name for unrelated
records in a single module. And if the records are related (and the
field is conceptually the same for the records), then you can use a
type class to overload the accessor name in a controlled fashion.

So why would you ever need to reuse the same field name in the same
module?


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


Re: [Haskell-cafe] Type Directed Name Resolution

2010-11-11 Thread Lauri Alanko
On Thu, Nov 11, 2010 at 03:17:39PM +0200, Michael Snoyman wrote:
 data PetOwner
 data FurnitureOwner
 
 data Cat = Cat { owner :: PetOwner }
 data Chair = Chair { owner :: FurnitureOwner }

These are clearly related uses, so as I said, you can use a type class
to overload the accessor name in a controlled fashion.


{-# LANGUAGE EmptyDataDecls, MultiParamTypeClasses, FunctionalDependencies #-}

data PetOwner
data FurnitureOwner

data Cat = Cat { catOwner :: PetOwner }
data Chair = Chair { chairOwner :: FurnitureOwner }

class Owned a b | a - b where
  owner :: a - b
  
instance Owned Cat PetOwner where  
  owner = catOwner
  
instance Owned Chair FurnitureOwner where
  owner = chairOwner


(You can also use associated type families for the same effect.)


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


Re: [Haskell-cafe] Gödel' s System T

2010-11-11 Thread Lauri Alanko
On Thu, Nov 11, 2010 at 04:04:07PM +, Aaron Gray wrote:
 On 11 November 2010 11:43, Petr Pudlak d...@pudlak.name wrote:
  Thanks Dan, the book is really interesting, all parts of it. It looks like
  I'll read the whole book.

 Watch out for the decidability issue though :-
 
 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.6483

Just to clarify, the issue is that you cannot convert System F to
implicitly typed Curry-style: the explicit type abstractions and type
applications are there for a reason. For the same reason, rank-N
polymorphism in Haskell requires explicit type annotations.

There's still nothing wrong with System F as it stands, though.


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


Re: [Haskell-cafe] Type Directed Name Resolution

2010-11-10 Thread Lauri Alanko
On Wed, Nov 10, 2010 at 11:59:28AM +0200, John Smith wrote:
 http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution

The problem with this is that it conflates two orthogonal features:
type-directed name resolution proper (also known as ad hoc
overloading), and a fancy postfix application syntax. There is no
connection between these except that both are useful for accessing
records in a particular way.

So the proposal seems to be tailored specifically to fix some
inconveniences with records. I'd much rather see a true record system
for Haskell, since that would fix the namespace conflict problem in a
more robust way.

Plain ad hoc overloading might or might not be a sensible addition to
Haskell, but please at least drop the x .f syntax, it's a pointless
hack that makes the lexical status of . even more difficult than it
currently is. After all, one can simply define e.g. x .$ f = f x if
postfix application is needed.

Cheers,


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


Re: [Haskell-cafe] Splittable random numbers

2010-11-10 Thread Lauri Alanko
On Thu, Nov 04, 2010 at 05:38:12PM +, Simon Peyton-Jones wrote:
 There's lots of material on generators that generate a linear
 sequence of random numbers, but much less on how to generate a tree
 of random numbers, which is what Haskell's System.Random API
 requires.

I'd like to understand what the fundamental difficulty is. I thought
that e.g. cryptographic PRNGs have the requirement that the output of
the PRNG cannot be used to guess its internal state (and thus the
future output). Hence one would think that a sufficiently strong PRNG
can be used to generate the seed for a new PRNG, which then shouldn't
have any observable similarity to the old PRNG.

So a naive implementation of split would be:

split g = (mkGen seed, g')
  where (seed, g') = random g

(Where mkGen creates a new state from some sufficiently big seed
data.)

So what is the problem here? What kinds of observable
interdependencies between split streams would come up with the above
definition using common PRNGs? Are my assumptions about the security
of cryptographic PRNGs incorrect, or is the issue simply that they are
too expensive for ordinary random number generation?


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


Re: [Haskell-cafe] Edit Hackage

2010-10-29 Thread Lauri Alanko
On Thu, Oct 28, 2010 at 01:55:12PM -0700, Don Stewart wrote:
 The number of subscribers to the Haskell Reddit, for example, is double
 the -cafe@, and there are comparable numbers of questions being asked on
 the Stack Overflow [haskell] tag, as here -- so anyone who only reads
 -cafe@ is already missing a lot of stuff.
 
 A lot of the community has already voted on the efficacy of mailing
 lists for large communities, by moving their discussion elsewhere.

Do you mean that people have actually unsubscribed from the list in
favor of only following web-based media? New people who only join the
web forums do not vote since they may not even know about the
mailing list.

I know that this is a hopeless battle, but since I feel very strongly
about this, I'll indulge in defending the mailing list even though
this is rather off-topic.

The reasons why I prefer mailing lists (and newsgroups, rest in piece)
over web-based discussion forums:

* Usability: mail and news clients provide a consistent interface to
  all the discussions, and the customizability and diversity of
  clients ensures that everyone can access the discussions the way
  they like it. In contrast, web forums come with their built-in
  interfaces, and if you don't like them, you are SOL.

* Scalability: related to the above, since mail and news provide a
  consistent interface to all the discussions, adding new lists and
  groups to be followed requires minimal effort since they just show
  up as new items whose updates get tracked automatically. In the
  worst case, adding a new web forum to be followed requires visiting
  the site frequently to check whether new messages have arrived. RSS
  and similar syndication technologies help, thankfully, but support
  for them is inconsistent, and often incomplete (they might not
  notify about new comments, only new topics). I subscribe to tens of
  mailing lists without problems. I wouldn't want to try to follow
  tens of web forums regularly.

* Archivability: with mail and news, it is trivial for me to get local
  copies of the discussions (and the messages I myself have written)
  which I can peruse and search to my heart's content later without
  being dependent on the continued functioning of some external
  service. Although it is possible to save web pages locally, this
  usually very inconvenient, especially if one wants the local copies
  to be kept up to date with ongoing discussions.

* Offline support: related to the above, with mail and news fetching
  and sending messages are separate from reading and writing
  them. Hence one can read and write messages even when one is for
  some reason not online. Web forums practically require an online
  connection when one wants to read the discussions.

* Neutrality: newsgroups are completely distributed and not controlled
  by any single entity. Mailing lists are a centralized service, but a
  purely technical one. The haskell.org mailing lists (like the rest
  of haskell.org) are directly maintained by the community. In
  contrast, external web forums like reddit and stackoverflow are
  owned by companies, and visits to the sites bring ad revenue to the
  companies. Moreover, the contents of these sites are subject to
  deletion (or perhaps even editing) by the whims of their owners.

In short, the old technologies of mail and news are technically vastly
superior to web forums, which have required additional technologies
(e.g. RSS) to attempt to overcome the obstacles that mail and news
solve directly.

It is true that web forums are nowadays very popular and have some
nice features that the older technologies don't. The main reason for
this, I suspect, is money: mail and news are from the older, more
innocent age when internet technology was driven by the desire to
communicate efficiently instead of making money. They are by their
nature so neutral that they provide no financial incentive to develop
them or support them. The web, on the other hand, provides many
opportunites to profit by offering services, so it is no wonder that
web technologies have flourished in the commercialized internet.

Perhaps this is inevitable, and it is certainly ok for the haskell.org
front page to provide links to reddit and stackoverflow just to inform
visitors that these sites might be of interest.

But by saying I encourage people to use the online forums: Haskell
Reddit and Stack Overflow you are effectively saying: please let
Condé Nast Digital and Stack Overflow Internet Services, Inc
capitalize on your interest in and knowledge of Haskell. I most
strongly object to this becoming the standard policy of the Haskell
community.

Cheers,


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


Re: [Haskell-cafe] In what language...?

2010-10-25 Thread Lauri Alanko
On Mon, Oct 25, 2010 at 10:10:56PM +0100, Andrew Coppin wrote:
 Type theory doesn't actually interest me, I just wandered what the
 hell all the notation means.

That sounds like an oxymoron. How could you possibly learn what the
notation means without learning about the subject that the notation
is about? That's like saying I'm not actually interested in calculus,
I'd just like to know what the hell all these funny S-like symbols
mean.

For what it's worth, I was once in a similar situation (modulo the
interest), and sent a similar query:

http://groups.google.com/group/comp.lang.functional/browse_frm/thread/bb82dcec463fd776

Following that, Pierce sent me a draft of his (then upcoming) book,
and I found it extremely accessible at my level (at least compared to
the other book I studied, Mitchell's Foundations, which, though full
of good information, was a bit hard to digest). So I will add voice to
those recommending TAPL.

Cheers,


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


Re: [Haskell-cafe] Re: Lambda-case / lambda-if

2010-10-07 Thread Lauri Alanko
On Thu, Oct 07, 2010 at 02:45:58PM -0700, Nicolas Pouillard wrote:
 On Thu, 07 Oct 2010 18:03:48 +0100, Peter Wortmann sc...@leeds.ac.uk wrote:
  Might be off-topic here, but I have wondered for a while why Haskell
  doesn't support something like follows:
  
do case (- m) of ...
  
  With the more general rule being:
  
do ... e (- m) g
  =
... m = \tmp - e tmp g

Your general rule doesn't subsume your case example, since a case
expression is not an application. I think you mean something like

 do C[(- m)]
=
 m = \tmp - C[tmp]

where C is an arbitrary expression context. It could further be
generalized to allow several (- ...) subterms in an expression, with
implied left-to right sequencing. Frankly, that seems like a very
attractive way to make the do-notation into a more practical
imperative sub-language.

This should probably also cover binding, i.e. do { p - C[(- m)];
... } should also work.

 Imagine these examples:
 
 do {a; b (- c) d; e} = do {a; x - c; b x d; e}
 
 do {a  b (- c) d; e}
   |
   +-- do {x - c; a  b x d; e}
   |
   +-- do {a; x - c; b x d; e}

To my understanding no rule would produce this latter variant. do {a;
b} is transformed into a  do {b}, not the other way around. The
proposed transformation rule seems clear to me: the context covers the
entire expression-statement, including of course expressions
containing monadic operations:

do {a  b (- c) d; e}  =  c = \x - a  b x d  e

and if you want a to go before c, you have to do

do {a; b (- c) d; e)=  a  c = \x - b x d  e

 Imagine that b can be equal to b1  b2 and so where placing the
 x - c is non obvious and it should be.

I don't see what this has to do with anything. All we are interested
in is the syntax of do-expressions. The do-transformation is
completely oblivious to monadic operations within the statements, it
only produces some more monadic operations.

Cheers,


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


Re: [Haskell-cafe] Slightly off-topic: Lambda calculus

2009-06-21 Thread Lauri Alanko
On Sun, Jun 21, 2009 at 05:53:04PM +0100, Andrew Coppin wrote:
 I've written a simple interpretter that takes any valid Lambda  
 expression and performs as many beta reductions as possible. When the  
 input is first received, all the variables are renamed to be unique.

 Question: Does this guarantee that the reduction sequence will never  
 contain name collisions?

With name collisions I'm assuming you mean inadvertent variable
capture. The answer depends on your evaluation strategy. If you never
reduce inside a lambda (e.g. call-by-name or call-by-value), then you
will always be substituting a closed term in place of a variable, and
nothing in a closed term can get captured.

However, if by as many reductions as possible you mean to normal
form, then you also need to reduce inside lambdas. Then the story is
different. Consider the following sequence of beta reductions:

(\x. x x) (\y. \z. y z)
- (\y. \z. y z) (\y. \z. y z)
- \z. (\y. \z. y z) z
- \z. \z'. z z'

Notice that in the original form, all variable names were unique, but
then the variable z got duplicated, and the last reduction happened
_inside_ the \z. expression, which required renaming of the inner
z in order to avoid variable capture and the erroneous result of
\z. \z. z z.

Hope this helps.


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


Re: [Haskell-cafe] Purely logical programming language

2009-05-26 Thread Lauri Alanko
On Tue, May 26, 2009 at 09:10:10PM +0200, Matthias Görgens wrote:
 The model in Prolog, however, looks more like the model used in most
 strict functional languages.  It uses impure predicates to affect the
 outside world.  Do you know of any attempt to do for logic programming
 what Monads did for functional programming?

Traditionally Prolog programmers have used chained state variables:

foo(X,S0,SOut) :- bar(X,S0,S1), baz(X,Y,S1,S2), quux(X,Y,S2,SOut).

This is kind of like using a state monad on top of Prolog's built-in
nondeterminism monad. There's even syntactic sugar for this, just like
Haskell programmers have the do-syntax:

foo(X) -- bar(X), baz(X,Y), quux(X,Y).

Although Prolog isn't pure, Mercury, its derivative, is (mostly). In
Mercury, the IO state (kind of like RealWorld) is threaded through
state variables and Mercury's mode checking makes sure that there will
always be only one result from IO predicates.

Mercury also has type classes and other Haskellisms, so if you're
interested in doing Prolog the Haskell way, you should definitely
have a look at it.


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


Re: [Haskell-cafe] IO trouble

2009-05-12 Thread Lauri Alanko
On Tue, May 12, 2009 at 04:59:36PM -0400, Xiao-Yong Jin wrote:
  f :: a - b
  g :: (a - b) - c - d

  gf :: c - d
  gf = g f
 
 Now I want to handle exceptions in f and redefine f as in f'
 
  f' :: a - IO (Either e b)
 
 So my question is how to define gf' now to use f' instead of
 f?
 
  gf' :: c - IO (Either e d)

Use Control.Monad.Error.ErrorT, it's exactly for this. You have to
monadize g to be able to pass f' as an argument to it.

f' :: a - ErrorT e IO b
g' :: Monad m = (a - m b) - c - m d
gf' :: c - ErrorT e IO d
gf' = g' f'

Here e should be some fixed instance of Error.

HTH.


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


Re: Laws and partial values (was: [Haskell-cafe] mapM_ - Monoid.Monad.map)

2009-01-24 Thread Lauri Alanko
On Fri, Jan 23, 2009 at 08:10:38PM -0500, rocon...@theorem.ca wrote:
 I'd like to argue that laws, such as monoid laws, do not apply to partial 
 values.  But I haven't thought my position through yet.

Before you do, you may want to read Fast and Loose Reasoning is
Morally Correct:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.59.8232


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


Re: [Haskell-cafe] How to check object's identity?

2009-01-04 Thread Lauri Alanko
On Sun, Jan 04, 2009 at 04:19:38PM +0800, Evan Laforge wrote:
 If you don't have set-car!, then identity and equality are impossible
 to differentiate.

There's still eqv?. (I wish people wouldn't use eq? as an example of
an identity-comparison operation. It's as underdefined as
unsafePtrEq.)

So although state implies identity, the converse is not true. You can
also have immutable objects with distinct identities.

Some dialects of Scheme have recently started leaning towards making
pairs immutable, but whether they should also make them
indistinguishable is a separate question:

http://groups.google.com/group/comp.lang.scheme/browse_thread/thread/7eccba9fb4eebb44

And having a limited form of observable identity has even been
proposed for Haskell:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.4053

Personally, I find the idea appealing (and have implemented the Refs
in the paper with IORefs and unsafePerformIO), because really, even
currently a programmer has to care about sharing since it can have
radical implications for performance and memory usage. Making it
observable in the program would just mean acknowledging the fact that
in real-world programming, you can't _really_ replace a variable with
its definition without changing its behavior in important ways.


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


Re: [Haskell-cafe] Rotating backdrop (aka learning Haskell)

2008-05-25 Thread Lauri Alanko
On Tue, May 20, 2008 at 09:15:57AM +0100, Yann Golanski wrote:
 1- Get a list out of a file:  I managed to do that using the following:
 
 parseImageFile :: FilePath - IO [String]
 parseImageFile file = do inpStr - readFile file
  return $ filter (/=) (breaks (=='\n') inpStr)

Note that there is a standard function lines which splits a string
into lines.

 Nice, simple and I understand what it is doing.  
 
 2- Get a random element from a list and remove it:  Okay, this I
 understand less well.  I looked at the solutions of problems 23 and 20
 in http://www.haskell.org/haskellwiki/99_questions so there is a
 skeleton there.   However, my list is IO [String] Hum, monads.
 
 Any pointers as to how to do that?

import System.Random

removeRandomElement :: [a] - IO (a, [a])
removeRandomElement l = do i - randomRIO (0, length l - 1)
   return (removeAt i l)

where removeAt is from problem 20 above.

And you use it like anything else in the IO monad:

do ...
   images - parseImageFile ...
   ...
   (chosen, rest) - removeRandomElement images
   ...

 3- Wait and do something later How, I have no idea how to do that!
 Help?

Control.Concurrent.threadDelay is the simplest way to make a thread
sleep for a while. However, if you're using some GUI library, you may
want to use the library's own timers.

 4- I guess that progress bars and updating text will be somewhere in the
 GUI (I chose wxHaskell)...  Again, no idea where.

I'm not familiar with wxHaskell, sorry.

 5- How do you call an external program in Haskell?  Either xv or
 Esetroot will do the job of displaying the image.  Is there a Haskell
 native way to do that?

There is a direct X11 library for Haskell, but you're probably better
off just calling an external program. See the System.Process module.

Hope this helps.


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


Re: [Haskell-cafe] one-way monads

2008-05-20 Thread Lauri Alanko
On Tue, May 20, 2008 at 07:54:33AM +0200, Zsolt SZALAI wrote:
 Here comes IO and one-way monads, where the internal state can not be
 extacted, and seems, that the internal data is global to the program.
 Hows that could be? Is it just because main::IO() or because the
 implementation of IO uses external C functions and there are no
 internal state in the monad itself at all?

There's nothing magical about the IO monad as a concept. It is true
that it is handled specially by the library and the compiler, but this
is just for performance reasons.

IO _could_ well be an ordinary datatype:

data IO a where
  Return :: a - IO a
  Bind :: IO a - (a - IO b) - IO b
  OpenFile :: FilePath - IOMode - IO Handle
  HPutChar :: Handle - Char - IO ()
  HGetChar :: Handle - IO Char
  HClose :: Handle - IO ()
  -- etc.

If it were implemented like this, then the only magic would be in the
runtime, which would take the IO value returned by the main function
and somehow execute it. But if the implementation of IO were like
this, and the datatype were exposed, then we could perfectly well
write a userlevel sandboxing function:

runVirtual :: IO a - VirtualWorld - (a, VirtualWorld)

Where VirtualWorld would be a sandbox that contains all the state
that IO operations can access: at least a filesystem, maybe something
else too. This would probably count as extraction.

As it happens, the IO monad is usually not implemented this way, but
more directly. Performance is here more important than transparency...


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


Re: [Haskell-cafe] Monad for HOAS?

2008-05-14 Thread Lauri Alanko
On Wed, May 14, 2008 at 03:59:23PM +0100, Edsko de Vries wrote:
 You mention that a direct implementation of what I suggested would
 break the monad laws, as (foo) and (Let foo id) are not equal. But one
 might argue that they are in fact, in a sense, equivalent. Do you reckon
 that if it is acceptable that foo and do { a - foo; return a } don't
 return equal terms (but equivalent terms), we can do still better?

If you just want the syntactic sugar and don't care about monads, in
GHC you can use plain do-notation:

{-# OPTIONS -fno-implicit-prelude #-}

import Prelude hiding ((=), fail)

data Expr = One | Add Expr Expr | Let Expr (Expr - Expr)

(=) = Let

fail = error

t :: Expr
t = do a - One
   b - Add a a
   Add b b

That's generally pretty icky, though.


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


Re: [Haskell-cafe] What is the role of $!?

2007-11-18 Thread Lauri Alanko
Please note that if you're using GHC, bang patterns are often much
more convenient than $! or seq when you want to enforce strictness:

http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html


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


Re: [Haskell] Fingerprints and hashing

2007-10-11 Thread Lauri Alanko
If compositionality is important, at least Rabin's fingerprints are
worth considering: http://citeseer.ist.psu.edu/broder93some.html

They have the neat property that the fingerprint of a concatenation of
strings can be cheaply computed from the fingerprints of the
constituents. I think this effectively means that the plusFP operation
can be made associative, which might offer optimization opportunities.

I remember implementing it some seven years ago when prototyping for a
C implementation. The code is lost, though. I can give it a shot
again, if this is considered a reasonable algorithm.


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


Re: [Haskell-cafe] haskell and reflection

2007-09-11 Thread Lauri Alanko
On Tue, Sep 11, 2007 at 07:33:54AM -0700, Greg Meredith wrote:
 Our analysis suggested the following breakdown
 
- Structural reflection -- all data used in the evaluation of programs
has a programmatic representation
- Procedural reflection -- all execution machinery used in the
evaluation of programs has a programmatic representation
 
 The Java notion of reflection is restricted entirely to the first case

Then what would you call ClassLoader.defineClass?

As for Haskell, there are various tools for both (at least
Data.Typeable and hs-plugins), but neither are truly type-safe: it is
possible to write code that uses these libraries and type-checks, yet
crashes. Static typing makes reflection very difficult to support
safely.

You might be interested in my MS thesis, where I explored these issues
in some more length: http://www.cs.helsinki.fi/u/lealanko/alanko04types.pdf


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


Re: [Haskell-cafe] positive Int

2007-08-02 Thread Lauri Alanko
On Thu, Aug 02, 2007 at 02:08:33PM -0700, David Roundy wrote:
 This would be a very nice type to have (natural numbers), but is a tricky
 type to work with.  Subtraction, for instance, wouldn't be possible as a
 complete function...

Of course it would. It would just have the type Nat - Nat - Integer.

This of course means that Nat wouldn't be an instance of Num. Tough
luck, and one more reason for more fine-grained algebraic class
hierarchy: Nat would be a semiring (as would booleans and finite sets
and regular expressions and whatnot).


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


Re: [Haskell-cafe] infinite list of random elements

2007-07-30 Thread Lauri Alanko
On Mon, Jul 30, 2007 at 02:40:35PM -0700, Chad Scherrer wrote:
 Given a list, say [1,2,3], I'd like to be able to generate an infinite
 list of random elements from that list, in this case maybe
 [1,2,1,3,2,1,3,2,3,1,2,...]. I'm using IO for random purely due to
 laziness (my own, not Haskell's).

You can be even lazier and let the Random library do more of the work
for you, seeing that it includes randomRs:

randomElts rg xs = map (arr !) (randomRs bds rg)
  where bds = (1, length xs)
arr = listArray bds xs


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


[Haskell] Re: Implicit Parameters

2006-03-02 Thread Lauri Alanko
On Wed, Mar 01, 2006 at 11:53:42AM +, Simon Marlow wrote:
 something along these lines is likely to be quite straightforward to
 implement, won't require any changes to the type system, and gives you
 a useful form of implicit parameters without any of the drawbacks.
 
 The main difference from implicit parameters would be that
 thread-local variables would be restricted to the IO monad.

These two paragraphs sound _heavily_ contradictory to me. The point of
implicit parameters (fluids or just parameters in Scheme) is that
they provide a controlled form of dynamic scoping without introducing
any stateful mess. Implicit parameters are useful in plain purely
functional code just to make certain values customizable without forcing
them to be propagated explicitely everywhere even though default values
are ok most of the time. Restricting them to the IO monad would severely
undermine their purpose.

Now, I wonder whether we really really really need to track implicit
parameters in the type system. After all, exceptions, too, introduce a
certain amount of impurity yet they work just fine in pure code. 
Couldn't the same kind of semantic trickery that was used in the
imprecise exceptions paper also be applied to Scheme-style parameter
objects?


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


[Haskell-cafe] Interactively used EDSLs

2005-10-17 Thread Lauri Alanko
Hello.

Are there any embedded domain specific languages that are meant to be
used interactively from a Hugs or GHCi prompt without requiring the
user to be acquainted with Haskell in general, only the DSL library?

For instance, a Haskell shell DSL that provided combinators for
creating and piping processes would fill this description, but I don't
think such a thing exists. Yet I do have a vague recollection that
there are some existing DSLs that can be used in such a way. Does
anyone have suggestions?

Thanks.


Lauri Alanko
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Mutable hash?

2004-10-23 Thread Lauri Alanko
On Thu, Oct 21, 2004 at 09:17:20AM -0400, Robert Dockins wrote:
 There is a hashtable in the IO monad:
 
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data.HashTable.html

Why is it in IO instead of the more general ST? IMHO _all_ mutable data
structures should be written for ST (or a generalization thereof), since
one can always use stToIO if operation in the IO monad is really
required.


Lauri Alanko
[EMAIL PROTECTED]
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Type conversion problems

2004-06-13 Thread Lauri Alanko
On Sun, Jun 13, 2004 at 11:15:28AM +0200, Christian Hofer wrote:
 fac :: Integer - Integer
 fac n = product [1..n]
 
 term :: Double - Integer - Double
 term x n = (-1.0::Double)**(fromInteger n) * (x**(fromInteger (2*n + 
 1))) /
  (fromInteger (fac (2*n + 1)))

Why do you have all those type annotations? Simply writing directly:

fac n = product [1..n]
term x n = -1 ** n * (x ** (2 * n + 1)) / fac (2 * n + 1)

gives you functions for which are inferred the types (which you can of
course also give explicitly if you want):

fac :: (Enum a, Num a) = a - a
term :: (Floating a, Enum a) = a - a - a

And the type variable a can then be instantiated for Double. If you
really need to take an Integer parameter, you only need a single
conversion:

term' x n = term x (fromIntegral n)

with the type:

term' :: (Floating a, Enum a, Integral b) = a - b - a

If all this looks confusing, then forget about polymorphism and just
give exact types in the type annotations:

fac :: Double - Double
fac n = product [1..n]

term :: Double - Double - Double
term x n = -1 ** n * (x ** (2 * n + 1)) / fac (2 * n + 1)

term' :: Double - Integer - Double
term' x n = term x (fromIntegral n)

Hope this helps.


Lauri Alanko
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Syntax for output-only arrows?

2004-06-08 Thread Lauri Alanko
When I use arrows, I find that many of my primitives are of type (a () b)
(for some arrow type a): they produce a value but don't take any input.
E.g. deterministic parsers are like this.

The syntactic sugar for arrows is lovely, but I find it a bit tedious
writing foo - () all the time. The syntax allows the output of arrows
to be ignored, why not input too?

Would it cause unreasonable parsing problems simply to allow a simple
expression of an arrow type to be a legal command inside a proc
expression, with an implicit - () input? Or are there other reasons
against it?

I for one find it extremely convenient that I can write purely
imperative code with a simple syntax like do { foo; bar; baz }. I'd
like similar simplicity when dealing with arrows, too.


Lauri Alanko
[EMAIL PROTECTED]
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Eval in Haskell

2003-06-02 Thread Lauri Alanko
[Moving to cafe, this is only barely Haskell-related.]

On Sun, Jun 01, 2003 at 04:16:36PM -0700, [EMAIL PROTECTED] wrote:
 Eval of the kind
   let x = 1 in eval x
 is plainly an abomination.

I agree, though not because of the optimization issues but rather
as a matter of principle: a closed variable should be _closed_, it
should not be visible to anything but the body of the let-expression
that binds it. And an externally acquired eval-able expression is
definitely anything but.

Nevertheless, this abomination is supported even by some scheme
implementations:

guile (define local-environment (procedure-syntax (lambda (exp env) env)))
guile (define (eval-where-x-bound exp)
... (let ((x 'foo)) (local-eval exp (local-environment  
guile (eval-where-x-bound '(list 'x x))
(x foo)

 Incidentally, restricting eval to top-level or standard bindings is 
 not a significant limitation. It is, in general, a very good practice
 to apply eval to closed expressions only.

This depends entirely on what you want to achive with eval, so I don't
think the in general is justified. If you just want to evaluate closed
expressions whose results are printable and readable, then you really
just have an embedded interpreter which happens to read the same
language as your source code.

On the other hand, it is common for perl programs and especially shell
scripts to eval configuration files with the explicit purpose that the
configuration file may alter variables which are bound in the main
program. For such usage, it is essential that the main program and the
evaled file access the same enviroment.

(Naturally a configuration file shouldn't be allowed to mess with
_everything_ in the main program, but I don't think perl allows detailed
adjustment of the bindings in the environment. Some schemes do, though.)


Lauri Alanko
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Eval in Haskell

2003-06-02 Thread Lauri Alanko
[We now have lost all pretence of topicality]

On Sun, Jun 01, 2003 at 08:43:03PM -0700, Ashley Yakeley wrote:
 Guile seems to be a bit sloppy in general. I think it just keeps a 
 dictionary of symbol bindings and passes it around at runtime.
 
 guile (eval '(define b 5))
 guile b
 5

This particular kind of sloppiness is pretty common in Scheme REPLs:

la:~$ kawa
#|kawa:1|# (eval '(define b 5))
#|kawa:2|# b
5
#|kawa:3|# 
la:~$ mzscheme
Welcome to MzScheme version 204, Copyright (c) 1995-2003 PLT
 (eval '(define b 5))
 b
5
 
la:~$ bigloo 
--
Bigloo (2.5c),--^, 
`a practical Scheme compiler'  _ ___/ /|/  
Wed Nov 27 10:49:16 CET 2002   ,;'( )__, ) '   
Manuel Serrano;;  //   L__.
email:'   \/  '
[EMAIL PROTECTED] ^   ^   
--

Welcome to the interpreter

1:= (eval '(define b 5))
b
1:= b
5
1:= 
la:~$ mit-scheme 
Scheme Microcode Version 14.9
MIT Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Scheme saved on Tuesday June 18, 2002 at 2:26:05 AM
  Release 7.7.1
  Microcode 14.9
  Runtime 15.1
  SF 4.40
  Liar (Intel i386) 4.115
  Edwin 3.112

1 ]= (eval '(define b 5) system-global-environment)

;Value: b

1 ]= b

;Value: 5

1 ]= 
End of input stream reached
Happy Happy Joy Joy.


... though admittedly it's a bit confusing, since define either binds
or assigns to a variable, depending on whether it was already bound.


Lauri Alanko
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: seeking ideas for short lecture on type classes

2003-01-27 Thread Lauri Alanko
On Mon, Jan 27, 2003 at 08:37:06PM +1100, Fergus Henderson wrote:
 I agree.  The above characterization is highly misleading.  It would be
 more accurate and informative to say that both Haskell and OO languages
 dispatch on the dynamic type of a value.

What is the dynamic type of a value in Haskell, apart from existentials
and Dynamic? Ordinary type class dispatch is all done based on the types of
variables, not their values. All the dispatching could even be done at
compile time by specializing everything...


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



Re: Interpret haskell within haskell.

2002-12-22 Thread Lauri Alanko
On Fri, Dec 20, 2002 at 01:43:07PM +0100, Frank Atanassow wrote:
 There is quite a bit of work on staged evalution, metaprogramming,
 quasiquotation, reflection and run-time code generation in typed and ML-like
 languages. It's a very active and, IMO, promising area of research.

Yes. Thanks for the references, some of them I hadn't been acquainted with.

I was already aware of MetaML, but I had mostly thought of it as a
sophisticated macro system. But of course if you defer some stages until
runtime you essentially get _some_ form of eval.

After quickly skimming through some of these papers, it seems that they
aren't really after the same thing as I am. Template Haskell is explicitly
a macro system, and MetaML seems to be designed for partial evaluation so
that even at the first stage (in the source code) we have _some_ idea of the
structure of the code that is to be generated. Specifically, it seems that
there is no way to dynamically generate identifiers from strings, and I
guess this makes real evaluation of arbitrary input impossible.

Staged computation is very interesting in its own right, but I'm after
something different. I don't really want eval as a language construct, I
want a language that makes it possible to _implement_ eval, among other
things.

Let's take Scheme for an example. R5RS Scheme includes eval, but by itself
it's not particularly interesting. An interpreter for a language is just a
program, after all, and a full scheme evaluator can be implemented in a
couple of hundred lines. So there's nothing magic about this:

(eval '(letrec ((fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1)))
 (fact 5))
  (scheme-report-environment 5))
== 120

The magic is _here_:

(begin (define a 5) (eval '(set! a (+ a 1)) (interaction-environment)) a)
== 6

Here (interaction-enviroment) is a run-time representation of the
compile-time environment. It makes possible two-way interaction between the
stages. Essentially, first-class environments are all the magic you need to
implement eval.

So what I'm looking for is adapting first-class environments, as well as
other forms of reflection that are found in lisps, Smalltalk, Java, and
other untyped languages, to static typing. And I want to do it properly with
minimal run-time checking:

eval :: Pi t . String - Env - Maybe t

Here t is an explicit run-time type parameter, and 'eval t s e' returns
'Just x' if 's' represents a well-formed expression that can be assigned
type 't' in the environment 'e' and reduces to 'x'.

There are lots of other issues, of course. But the point is that I'm not so
much interested in code-generation mechanisms but rather in how to reify
compile-time information on the program as run-time objects.

Optimally, I'd like a system that allows the definition of new types at
runtime and possibly even gradual hot-swapping of the entire codebase of the
program. All with type-safety.

So is there any research on this sort of thing?

(This isn't really Haskell-specific, so this is probably somewhat off-topic
for haskell-cafe. Sorry about that, but I don't really know of a better
place to discuss this. When I tried to query about this on the Types forum,
the moderator rejected my posting as too rambling, which was of course
perfectly accurate :). I haven't yet managed to write up a more lucid
exposition of the issue...)


Lauri Alanko
[EMAIL PROTECTED]

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



Re: Interpret haskell within haskell.

2002-12-20 Thread Lauri Alanko
For what it's worth, I will probably be doing my MSc thesis on
adapting eval (and reflection in general) to a statically typed
language. Essentially you need a run-time representation of the
environment and the typing context, and a type system which groks the
relationship between run-time and static types.

Strangely enough, I haven't found any real research on this particular
subject. There's lots of work on related areas, eg. dynamic types and
intensional polymorphism, but nothing that's really motivated by eval
and reflection.

Any suggestions for references are welcome. :)


Lauri Alanko
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



Re: Constructors in GHC

2002-12-11 Thread Lauri Alanko
On Wed, Dec 11, 2002 at 11:40:39AM -, Simon Peyton-Jones wrote:
 We could make this more consistent in two ways.  Alternative (A): One
 way would be to make it clearer that $wMkT was the real constructor:
 
   data T = $wMkT Int Int
   MkT p = case p of (x,y) - $wMkT x y
   f x y = $wMkT x y
   g t = case t of $wMkT x y - x
 
 This is consistent, but it makes External Core a bit funny.  (The real
 constructors are always $w things.)  

Speaking as a common user who hasn't used External Core for anything,
this one looks much more attractive to me. Consistency and predictable
typing is important, and it's ok for things to look funny because,
after all, funny things _are_ going on when special optimizations are
applied.


Lauri Alanko
[EMAIL PROTECTED]
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Proposals for changes to searching behaviour

2002-12-09 Thread Lauri Alanko
On Mon, Dec 09, 2002 at 12:40:18PM -, Simon Marlow wrote:
   - The sources for a module A.B.C would be allowed to be placed
 in either A.B.C.hs or A/B/C.hs relative to one of the directories
 in the search path.  Currently only A/B/C.hs is allowed.

 Please let us know if either of these would make your life easier, or if
 there's anything else you'd like to see.

Since the problem is often that your program/library has a managable
depth, but it is _located_ very deep in the hierarchy (eg. User.*
modules if you have a long and complicated domain), then how about
allowing A.B/C.hs for module A.B.C? Then you don't need to have a
long, mostly empty dummy hierarchy.


Lauri Alanko
[EMAIL PROTECTED]
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Strings are slow

2002-11-19 Thread Lauri Alanko
Hello. Here's a grep program:


module Main where

import Text.Regex
import System.IO
import System.Environment
import Control.Monad
import Data.Maybe

main = do [re] - getArgs
  let rx = mkRegex re
  let loop = do line - getLine
when (isJust (matchRegex rx line)) (putStrLn line)
eof - isEOF
unless eof loop
  loop


It turned out that this is remarkably slow. The first problem was with
inlining. If this is compiled with ghc-5.04 -O -ddump-simpl, I get:

  case GHC.IOBase.unsafePerformIO
 @ (Data.Maybe.Maybe
(GHC.Base.String,
 GHC.Base.String,
 GHC.Base.String,
 [GHC.Base.String]))
 (Text.Regex.Posix.regexec (Text.Regex.mkRegex re) a731)
  of wild4 {

Ie. the regex is compiled anew every time a string is matched. A bug?

Anyway, without optimization the code produced is reasonable, but still
horrendously slow. Testing with a simple word as a pattern from a 7.3MB,
800kline file, the running time was 37.5 seconds. For comparison, a similar
program in mzscheme (interpreted!) took 7.3 seconds while the system
grep, of course, took 0.4 seconds.

I did some profiling by creating new top-level bindings for matchRegex
and getLine (is there a better way?):


total time  =   53.34 secs   (2667 ticks @ 20 ms)
total alloc = 1,172,482,496 bytes  (excludes profiling overheads)

COST CENTREMODULE   %time %alloc

match  Main  69.7   56.8
getl   Main  23.9   40.2
main   Main   6.33.0


So it seems like all the time is spent just converting ByteArrays to
char lists to C arrays. This makes me wonder how sensible it really is
to represent strings by char lists. Yes, it's nice and uniform and lazy,
but...

How can I get this faster, then? PackedStrings are not very useful
because they just don't support enough operations (getline, matchregex)
alone, and having to convert them to Strings sort of defeats their
purpose. _Any_ operation that provides only a String interface condemns
us to a gazillion allocations. And by default all char*-based foreign
interfaces are represented with Strings on the Haskell side.

Maybe a generic Textual class with at least String and PackedString (and
ByteArray?) as instances would help? Then the common string-based
operations could all have separate implementations for separate
representations. With heavy specialization, of course. This would be
especially useful if the FFI (especially withCString) supported it.

Or alternatively, maybe the foldr/build rewriting trick could be used to
eliminate some redundant conversions between representations?

Just throwing ideas in the air here.


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Formatting function types

2002-11-18 Thread Lauri Alanko
Just a silly thing that's been nagging me. a very common way (at least
in the base libraries) of formatting function types seems to be this:

hPutBuf :: Handle   -- handle to write to
- Ptr a-- address of buffer
- Int  -- number of bytes of data in buffer
- IO ()

I remember when I first started learning Haskell, and these many-arrowed
functions seemed very strange to me: Okay, we give it a handle, and get
a pointer, and, um, from this we get an int, and from this an action?
Er?

The problem here is that the first parameter has a distinguished look
while the other parameters and the return value all look the same. I
think that a naive reader is inclined to assume that line breaks are
situated at major structural boundaries. Consider two different
interpretations of the structure of the type term:

  (((Handle   (Handle
  - Ptr a) -(Ptr a
  - Int)   -(Int
  - IO ()) - IO (

Which looks more natural?

The point of this rant is just this: the aforementioned multi-line
formatting style should only be used for left-associative infix
operators. For right-associative ones (such as the function arrow), the
One True Way is this:

Handle -
Ptr a -
Int -
IO ()

Nuff said.


Lauri Alanko
[EMAIL PROTECTED]

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



OT: broken mail threads

2002-08-20 Thread Lauri Alanko

I'm sorry to bring up such petty issues, but this has been nagging me
for quite a long while now... 

The Haskell mailing lists have one rather unflattering characteristic:
their mail threads are almost always broken.

I'll elaborate. Most mail user agents arrange messages in threads,
keeping track of which message is a reply to which. The programs use the
In-Reply-To: and References: -headers of the messages for this.

By some coincidence, the various Haskell mailing lists have an
uncommonly high proportion of replies which do not have these headers.
As a result, many followup messages show up as a new thread in the
unlucky reader's mail program, and this makes following a discussion
more inconvenient. This also affects web archives of the mailing lists.

The reason for these lacking headers is most likely faulty mail
programs. Since programs are at fault here, not people, I won't mention
names, but will simply identify the most common broken user agents.

X-Mailer: Claris Emailer 2.0v3, January 22, 1998
(No threading information of any kind)

X-Mimeole: Produced By Microsoft Exchange V6.0.6249.0
(Does have some very non-standard Thread-Topic: and Thread-Index:
-headers, but no In-Reply-To: or References:)

User-Agent: slrn/0.9.7.4 (Linux)
(Apparently via a mail-news -gateway. Replies do have a References:
-header, but with locally generated message-ids instead of the real
ones.)

There are also other messages with threading problems, but these are by
far the most common sources.

If you find yourself using one of these programs, could you please check
your configuration or maybe consider switching to a more well-behaving
user agent? This would make your messages much easier to follow.

Thanks.


Lauri Alanko
[EMAIL PROTECTED]

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



Re: e :: Double

2002-05-02 Thread Lauri Alanko

On Thu, May 02, 2002 at 02:12:53PM +0400, Serge D. Mechveliani wrote:
 Please, has Haskell  e :: Double  
 
 ( ~= limit (1 + 1/n)^n ) in its standard library? 

exp 1.0


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



Re: check for exhaustive patterns is broken

2002-03-04 Thread Lauri Alanko

On Mon, Feb 11, 2002 at 05:37:32PM +0100, Feliks Kluzniak wrote:
  I would replace the last guard with 'otherwise'.
 
 Strangely enough, this particular solution never occurred to me. Not
 as pretty as the original, but thanks!

A somewhat prettier solution would maybe be to use Ord.compare:

case (compare k k') of LT - ... ; GT - ... ; EQ - ...

This might even be faster if comparison is expensive.


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs



Re: functions not in type classes

2002-01-19 Thread Lauri Alanko

On Fri, Jan 18, 2002 at 12:27:09AM -0800, Ashley Yakeley wrote:
 Well, what classes should such functions as const, id and (.) be members 
 of?
 
 const :: a - b - a;
 const x y = x;
 
 id :: a - a;
 id x = x;
 
 (.) :: (b - c) - (a - b) - (a - c);
 (.) f g x = f (g x);

Arrows, of course. :) In fact, this is directly from my personal,
somewhat tweaked arrow library:

class Arrow z where
arr :: (a - b) - z a b
-- at least two of , = and first must must be defined
-- (preferably  and first, or things get slow...)
() :: z a b - z b c - z a c
a  b = a = first b = arr (\((a,_),_) - a)
(=) :: z a b - z (b,a) c - z a c
a = b = save a  b
first :: z a b - z (a, c) (b, c)
first a = (fst  a) = arr (\(b,(a,c)) - (b,c))
id :: z a a
id = arr (P.id)
const :: a - z q a
const a = arr (P.const a)

The idea is that arrows that id-arrows and const-arrows can be given
specialized implementations. For instance, we can have a direct term
implementation for the arrows:

data Term z a b 
= Arr (a - b)
| Lift (z a b)
| forall q . Term z a q : Term z q b
| forall q r s . First (Term z a (q,s)) (Term z q r) (Term z (r,s) b)
| Id (Term z a b)
| Label String (Term z a b)
| Const b
| Null -- unsafe

instance Arrow z = Arrow (Term z) where
arr f = Arr f
a  b = a : b
first a = First Null a Null
const = Const
id = Id Null

And then one can optimize them right inside the Haskell program:

reduce :: Arrow z = Term z a b - Term z a b
reduce (Const a : Arr b) = reduce (Const (b a))
reduce (Arr a : Const b) = reduce (Const b)
reduce (Arr a : Arr b) = reduce (Arr (b . a))
-- ...

And after optimization run it again as a real arrow:

runTerm :: Arrow z = Term z a b - z a b
runTerm (Arr f) = arr f
runTerm (Lift z) = z
runTerm (a : b) = runTerm a  runTerm b
-- ...

I never actually pursued this idea to the end, though, so I don't know
if this would be useful in practice. But still, it's a neat idea, and
gives a reason why const should be in a class. :)


Lauri Alanko
[EMAIL PROTECTED]


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



Re: Report Issues

2002-01-04 Thread Lauri Alanko

What, by the way, is the rationale behind including /= in the Eq class in
the first place? 

Since /= is intended to be semantically equivalent to \x y - not (x == y),
the only plausible reason for making it overloaded is optimization. But an
optimized implementation of /= can at most be two not:s faster than just
using not and ==, so the performance benefits seem quite minimal here. This
is nothing compared to, say, Monad., where an optimized implementation can
be quite a lot faster than the default one that uses =.

So as far as I see, the overloadability of /= is just a source of subtle
errors, when the implementation doesn't follow the expected (but
non-language-enforceable) semantics.


Lauri Alanko
[EMAIL PROTECTED]

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



Problem with xargs and ar

2001-10-25 Thread Lauri Alanko

Hello. Just a nasty build bug with 5.02 that I encountered.

When building the prelude library, the individual object files are
turned to an archive with xargs ar q libHSstd.a. Now, for some reason,
on this system, GNU ar fails at some point during this process. The
standard solaris ar works all right.

Ar is not the issue here. I've probably blundered something with the
installation of gnu ar, or it's buggy, or something.

The problem is that once ar has failed, and the xargs has failed, and
make has halted, an _incomplete_ libHSstd.a has been created. So one can
just run make again, and compilation proceeds, since the libHSstd.a
dependency has been satisfied.

The way to fix this is of course just to build the archive to a
temporary file, and once the xargs has completed successfully, rename it
to libHSstd.a.

Sorry for not being more verbose. I'm too tired from having fought for
days trying to compile ghc with a _working_ ghci on this solaris
machine... it took literally a minute to build hugs. :)


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs



Polymorphic data types fubar in ghci

2001-06-16 Thread Lauri Alanko


Something's seriously broken in current (built today from CVS) ghci:


module Tst where

data List a = Nil | Cons a (List a) deriving Show

len Nil = 0
len (Cons _ l) = 1 + len l

data SList = SNil | SCons String SList deriving Show

slen SNil = 0
slen (SCons _ l) = 1 + slen l


Prelude :l Tst.hs
Compiling Tst  ( Tst.hs, interpreted )
Ok, modules loaded: Tst.
Tst Cons foo Nil
*** Exception: loop
Tst len (Cons foo Nil)
*** Exception: loop
Tst SCons foo SNil
SCons foo SNil
Tst slen (SCons foo SNil)
1

Yet the compiler works okay, and compiled files work in ghci...

Prelude :l Tst
Skipping  Tst  ( Tst.hs, ./Tst.o )
Ok, modules loaded: Tst.
Tst Cons Foo Nil
Cons Foo Nil
Tst len (Cons foo Nil)
1

So it's clearly something with the interpreter.


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs



Void type and :m

2001-05-29 Thread Lauri Alanko


Two bugs. Firstly, the notorious void type

newtype Void = Void Void

makes ghc -O go in an infinite loop in the strictness analysis phase.
Without optimization it works fine. (It would be very nice if Void could be
eliminated _completely_, ie. Void - a would have the same representation as
a alone, but this is just wishful thinking...)

Secondly, the :m command in ghci does not accept underscores in module names.

Both are still present in CVS as of May 29th.


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs



Re: MonadError and fundeps

2001-05-11 Thread Lauri Alanko

On Fri, May 11, 2001 at 02:14:24PM +0200, Marcin 'Qrczak' Kowalczyk wrote:
 On Fri, 11 May 2001, Lauri Alanko wrote:
 
  Why? This makes composing and subtyping impossible:
  
  instance (MonadTrans t, MonadState s m, Monad (t m)) 
   = MonadState s (t m) where
  get = lift get
  put = lift . put
 
 This instance is illegal anyway. One of types in the instance head must be
 a type constructor applied to something (type variables in Haskell 98,
 anything with -fglasgow-exts).

Ah. So it seems. Pardon. It works in Hugs, though.

 Even if it was legal, it would overlap with
 instance Monad m = MonadState s (StateT s m)

Yep, but in hugs +o the latter overrides the first one. Which is quite
convenient.

 Also MonadReader and MonadWriter can't have such generic instances anyway
 because their methods have values of type 'm a' as arguments.

Oh?

translift :: (MonadTrans t, Monad m, Monad (t m)) 
   = (m a - m b) - t m a - t m b
   
translift f m = m = lift . f . return

instance (MonadTrans t, MonadReader r m, Monad (t m)) 
= MonadReader r (t m) where
ask = lift ask
local = translift . local

instance (MonadTrans t, MonadWriter w m, Monad (t m), Monoid w) =
MonadWriter w (t m) where
tell = lift . tell
listen = translift listen
pass = translift pass


 OTOH without the fundep there are ambiguities. For example:
 
 class ParsingState s where
 stateInput :: s - String
 stateSkip  :: Int - s - s
 
 instance ParsingState String where ...
 instance ParsingState s = ParsingState (s, Pos) where ...
 
 input :: (ParsingState s, MonadState s m) = m String
  -- Ambiguous without the fundep.
 input = gets stateInput

So it is, and why not? Is it inconceivable that m might actually have
multiple ParsingStates, and thus you really have to specify which one you
want to use to get the input?


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Existential datatypes with contexts crash ghci

2001-04-29 Thread Lauri Alanko

Hello. Given the source:


module GHCITst where

data Q = forall x . Show x = Q x

showQ (Q x) = show x


GHCi behaves like this:

   ___ ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |  GHC Interactive, version 5.01, For Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package std ... linking ... done.
Prelude :l GHCITst
Compiling GHCITst  ( GHCITst.hs, interpreted )
Ok, modules loaded: GHCITst.
GHCITst showQ (Q foo)
Segmentation fault


The behavior is the same for 5.00. Tested both on debian-unstable, linux
2.4.4, glibc-2.2.2, gcc-2.95.4 and redhat 6.1, linux-2.2.19, glibc-2.1.3,
egcs-1.1.2.

Prithee, somebody fix this, I would _so_ love to migrate from hugs and get
all the yummy ghc extensions and hslibs when using an interpreter. :)


Lauri Alanko
[EMAIL PROTECTED]

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs