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

2009-01-03 Thread Anton van Straaten

Luke Palmer wrote:
I, like many arrogant Haskellers, reject Scheme and other such impure 
languages as "functional".  At least until I turn on my brain.


If Haskell is functional, then so is Scheme - it's just that Scheme lets 
you use IORefs and the IO monad without going to nearly as much trouble.


Anton

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


Re: [Haskell-cafe] Updating doubly linked lists

2009-01-03 Thread S. Günther
G'Day,

and phew... quite a lot of code to grok. Thanks for the answers, they're much
appreciated.

On Sun, Jan 4, 2009 at 1:43 AM, Niklas Broberg  wrote:
>
> What you need is for the nodes to keep track of the length of the
> list. Here's a different solution from that oleg posted, to me it's
> slightly more intuitive, since the updates work directly on the dlists
> instead of via (elegant) proxy functions.
>
I had exactly the same thoughts after I realized that, if one wants to
update only
the non cyclic part of the list one has to know where the non cyclic
part ends. But
the only way to know that, is by keeping track of the length of the
list and using
this to find out when to tie the knot. So your solution is also more
intuitive to
me but if I'm not mistaken it has update complexity linear in the number of
elements in the list whereas Oleg's solution is logarithmic.

> mkRestDList :: Int -> [a] -> DList a -> DList a -> (DList a, DList a)
> mkRestDList _ []  _ farRight =
>(farRight, farRight) -- will only happen if the initial list is singleton
> mkRestDList len [x] nearLeft farRight =
>let this = DNode len nearLeft x farRight
> in (this, this)
> mkRestDList len (x:xs) nearLeft farRight =
>let this = DNode len nearLeft x nearRight
>(nearRight,farLeft) = mkRestDList len xs this farRight
> in (this,farLeft)
>
> updateRestD :: Int -> DList a -> DList a -> DList a -> (DList a, DList a)
> updateRestD 0 _ _ farRight =
>(farRight, farRight) -- will only happen if the initial list is singleton
> updateRestD 1 (DNode len _ x _) nearLeft farRight =
>let this = DNode len nearLeft x farRight in (this, this)
> updateRestD n (DNode len _ x r) nearLeft farRight =
>let this = DNode len nearLeft x nearRight
>(nearRight,farLeft) = updateRestD (n-1) r this farRight
> in (this,farLeft)
> updateRestD _ Empty _ _ = undefined -- can't happen
>
I think you can drop the second case in those two functions if you rewrite the
first case like this:
mkRestDList _ []  nearLeft farRight = (farRight, nearLeft)
resp.
updateRestD 0 _ nearLeft farRight = (farRight, nearLeft)


On Sat, Jan 3, 2009 at 8:51 PM,   wrote:
>
> Stephan Guenther wrote:
>
> The algorithm is essentially imperative (and so permits identity
> checking and in-place `updates') but implemented purely
> functionally. No destructive updates are ever used. Therefore, all the
> changes can be undone and re-done, and the code is MT-safe. The code
> is easily generalizable to 2D.
Thanks for your answer. As I'll explain below I also thought about
using a Map for
the 2D case, but wouldn't have thought of it in the one dimensional case as my
intuition would have been to use Niklas' solution there. Thanks for putting my
thoughts in a different direction.
Yet the thing that really puzzled me in the list case was, that I was
searching for
a solution without using auxiliary data like the length or delegating
the update to a
data structure which already supported it. I'm pretty sure by now that its
impossible without using zippers or something else.
> It is not for nothing Haskell is called the best imperative
> language. One can implement imperative algorithms just as they are --
> purely functionally, without any monads or other categorical notions.
Amen to that.

> -- The insert operation below makes a cyclic list
> -- The other operations don't care
> -- Insert to the right of the current element, if any
> -- Return the DL where the inserted node is the current one
> insert_right :: a -> DList a -> DList a
> insert_right x dl | is_empty dl =
>   let ref = dl_counter dl
>   -- the following makes the list cyclic
>   node = Node{node_val = x, node_left = ref, node_right = ref}
>   in DList{dl_counter = succ ref,
>dl_current = ref,
>dl_mem = IM.insert ref node (dl_mem dl)}
>
> insert_right x d...@dlist{dl_counter = ref, dl_current = curr, dl_mem = mem} =
>  DList{dl_counter = succ ref, dl_current = ref,
>dl_mem = IM.insert ref new_node $ IM.insert curr curr_node' mem}
>  where
>  curr_node = get_curr_node dl
>  curr_node'= curr_node{node_right = ref}
>  new_node  = Node{node_val   = x, node_left = curr,
>  node_right = node_right curr_node}
Could it be that there's a small inconsistency in the fact that if you
don't update the
left_node ref of curr_node? This is nearly never a problem except when you do
insert_right on a DList with only one element. In that case node_left
of curr_node
references itself and should be updated to reference it's new right
(and therefore
also left wraparound) neighbour. If I'm right this leads to the fact
that DList is only
right cyclic while the left end always wraps around to itself.
I know that this is easily corrected (if wanted), I just want to know if I'm
understanding the code correctly.

On Sat, Jan 3, 2009 at 10:37 PM, Apfelmus, Heinrich
 wrote:
> Ah, so you have a rectangular (or later hexagonal?) 2D grid? I suggest
> representing it as
>

Re: [Haskell-cafe] Type Family Relations

2009-01-03 Thread Thomas DuBuisson
Thank you all for the responses.  I find the solution that omits type
families [Diatchki] to be too limiting while the solution 'class (Dual
(Dual s) ~ s) =>' [Ingram] isn't globally enforced.  I've yet to
closely study your first solution, Ryan, but it appears to be what I
was looking for - I'll give it a try in the coming week.

Tom

On Sat, Jan 3, 2009 at 8:18 PM, Iavor Diatchki  wrote:
> Hello,
> Usually, you can program such things by using super-classes.  Here is
> how you could encode your example:
>
> {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
> FlexibleInstances #-}
>
> class HeaderOf addr hdr | addr -> hdr
> class HeaderOf addr hdr => AddressOf hdr addr | addr -> hdr
>
> data IPv4Header = C1
> data IPv4   = C2
> data AppAddress = C3
> data AppHeader  = C4
>
> instance AddressOf IPv4Header IPv4
> instance HeaderOf IPv4 IPv4Header
>
> {- results in error:
> instance AddressOf AppHeader AppAddress
> instance HeaderOf AppAddress [AppHeader]
> -}
>
> Hope that this helps,
> Iavor
>
>
>
> On Sat, Jan 3, 2009 at 7:22 AM, Thomas DuBuisson
>  wrote:
>> Cafe,
>> I am wondering if there is a way to enforce compile time checking of
>> an axiom relating two separate type families.
>>
>> Mandatory contrived example:
>>
>>> type family AddressOf h
>>> type family HeaderOf a
>>>
>>> -- I'm looking for something to the effect of:
>>> type axiom HeaderOf (AddressOf x) ~ x
>>>
>>> -- Valid:
>>> type instance AddressOf IPv4Header = IPv4
>>> type instance HeaderOf IPv4 = IPv4Header
>>>
>>> -- Invalid
>>> type instance AddressOf AppHeader = AppAddress
>>> type instance HeaderOf AppAddress = [AppHeader]
>>
>> So this is  a universally enforced type equivalence.  The stipulation
>> could be arbitrarily complex, checked at compile time, and must hold
>> for all instances of either type family.
>>
>> Am I making this too hard?  Is there already a solution I'm missing?
>>
>> Cheers,
>> Tom
>> ___
>> Haskell-Cafe mailing list
>> Haskell-Cafe@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2009-01-03 Thread Luke Palmer
2009/1/3 Xie Hanjian 

> * Luke Palmer  [2009-01-03 18:46:50 -0700]:
>
> > 2009/1/3 Xie Hanjian 
> >
> > > Hi,
> > >
> > > I tried this in ghci:
> > > >Prelude> 1:2:[] == 1:2:[]
> > > True
> > >
> > > Does this mean (:) return the same object on same input,
> >
> >
> > Also, in functional programming, *every* function returns the same output
> > for the same input.  That's part of the definition of function.  :-)
>
> This is true in Haskell, but may not true in Scheme (I guess also false
> in Lisp).


I, like many arrogant Haskellers, reject Scheme and other such impure
languages as "functional".  At least until I turn on my brain.

So, revise the beginning of my statement to "Also, in *pure* functional
programming, ..."

Luke


>
> In DrScheme:
>
>  >(eq? (cons 1 2) (cons 1 2))
>  #f
>  >(equal? (cons 1 2) (cons 1 2))
>  #t
>
> Although equal? treats the two as the *same*, they're different lists
> because if we modify one (e.g by set-car!) the other won't be affected.
>
> So here comes another question: when we say a function always give the
> same output for the same input, what the *same* means here? ídentity
> or equality?
>
> Thanks
> Jan
>
> >
> > Luke
>
> > ___
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
> --
> jan=callcc{|jan|jan};jan.call(jan)
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Use of abbreviations in Haskell

2009-01-03 Thread Thomas DuBuisson
Cafe,
I was going to write about this earlier, but I'm so ill read on the
record selector papers that I deleted the draft.

My proposal would be for each selector name to be a special type of
"phantom" type class (existing in the intermediate language only).
This type class would not be accessible by the programmer and thus
s/he couldn't make a polymorphic function for which specialization
would be needed.  In other words -  in normal circumstances there is
no need for dictionaries and thus no run-time difference between this
method and using different record names.

Example:

> data IPv4Hdr = Hdr4 { src, dst :: IPv4 }
> data IPv6Hdr = Hdr6 { src, dst :: IPv6 }
>
> func4 :: IPv4Hdr -> IO ()
> func4 hdr = do
> let s = src hdr
> ...
>
> func6 :: IPv6Hdr -> IO ()
> func6 hdr = do
> let s = src hdr
> ...

At some intermediate stage you'd see:

> class Src h s where
> src :: h -> s
> class Dst h d where
> dst :: h -> d
>
> instance Src IPv4Hdr IPv4 where
> src (IPv4 s _) = s
> instance Dst IPv4Hdr IPv4 where
> dst (IPv4 _ d) = d
> -- repeat for IPv6

The only point of frustration I see is if the programmer manually
makes both data types an instance of a programmer-visible type class,
thus making a polymorphic function.

> class IPHdr a
> instance IPHdr IPv4Hdr
> instance IPHdr IPv6Hdr
>
> sendPing :: (IPHdr a) => a -> IO ()
> sendPing p = networkSend (dst p) pingPayload

In this case I'd vote for specializing the function so there still
aren't any extra dictionaries, but I know that is not always optimal.

Tom

On Sat, Jan 3, 2009 at 10:08 PM, Isaac Dupree
 wrote:
> Ketil Malde wrote:
>> A module may be defined in a file with a name corresponding to the
>> module name, or any dot-separated prefix of it?  I.e. the file
>> Foo/Bar.hs will define module Foo.Bar and optionally Foo.Bar.Baz as
>> well?
>>
>> GHC should then be able to find it, and I believe it already has a
>> prioritized search mechanism (presumably, the file could be named
>> Foo.Bar.hs, too).
>
> I don't think GHC actually allows that (Foo.Bar.hs, ever). But your suggestion
> could work.
>
> 1. Try Foo/Bar/Baz.hs ; if it exists, end search (and error if it does not
> contain Foo.Bar.Baz, obviously as the file's top-level module).
> 2. Try Foo.Bar.hs ; if it exists, end search (and error if it does not contain
> Foo.Bar.Baz, obviously as a sub-module).
> 3. Try Foo.hs ; if it exists, end search (and error if it does not contain
> Foo.Bar.Baz, obviously as a sub-module... or possibly as a sub-sub-module?).
> 4. give up :-)
>
> Note though, that local modules tempt us to a couple other things too, even
> though they're not necessary to the proposal and would complicate it:
> - access-controlled modules (e.g. if other code can't import Foo.Bar.Baz)
> - relative-path imports / module names (e.g. if in Foo/Bar.hs we make Baz and
> try to import it some way with "import Baz")
>
> and as we already mentioned, it would likely involve some implicit importing
> of the sub-module.
>
> translating into ordinary haskell:
> I think my module-search mechanism makes a well-defined, deterministic way to
> find the right module, no complex translation necessary (except layout rule
> madness maybe?).
> Implicit importing: submodule syntax implies adding an "import
> The.Module.Name" line at that point in the containing file.  This would 
> suggest
> that submodules must be at the top, among the imports, because all imports
> must syntactically be at the beginning of the file -- and there's a reason for
> this.  Bother!  Even if the reason is dependency chasing, one would think
> same-file dependencies aren't important, but the submodules themselves can
> import things from other files, so those lines should need to be near the
> beginning anyway.
>
> so an example could be
>
> module MyData
> (
> module MyData.Sub,  -- or equivalently, D(..)
> transform
> )
> where
>
> module MyData.Sub  --or "module Sub" ?? that seems a bit too ad-hoc though
> where
>  data D = E | F
>
> transform :: D -> D
> transform F = E
> transform E = F
>
>
> ~Isaac
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2009-01-03 Thread Xie Hanjian
* Luke Palmer  [2009-01-03 18:46:50 -0700]:

> 2009/1/3 Xie Hanjian 
> 
> > Hi,
> >
> > I tried this in ghci:
> > >Prelude> 1:2:[] == 1:2:[]
> > True
> >
> > Does this mean (:) return the same object on same input,
> 
> 
> Also, in functional programming, *every* function returns the same output
> for the same input.  That's part of the definition of function.  :-)

This is true in Haskell, but may not true in Scheme (I guess also false
in Lisp).

In DrScheme:
  
  >(eq? (cons 1 2) (cons 1 2))
  #f
  >(equal? (cons 1 2) (cons 1 2))
  #t

Although equal? treats the two as the *same*, they're different lists
because if we modify one (e.g by set-car!) the other won't be affected.

So here comes another question: when we say a function always give the
same output for the same input, what the *same* means here? ídentity
or equality?

Thanks
Jan

> 
> Luke

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


-- 
jan=callcc{|jan|jan};jan.call(jan)


pgpBNyEg1SLvQ.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ANN: bytestring-trie 0.1.1 (bugfix)

2009-01-03 Thread wren ng thornton


-- bytestring-trie 0.1.1 (bugfix)


An efficient finite map from (byte)strings to values.

The implementation is based on big-endian patricia trees, like 
Data.IntMap. We first trie on the Word8 elements of a Data.ByteString, 
sharing string prefixes where possible, and then trie on the big-endian 
bit representation of those elements. Patricia trees have efficient 
algorithms for union and other merging operations, but they're also 
quick for lookups and insertions.




-- Changes


* Fixed a bug in lookupBy_ pointed out by Maxime Henrion. The bug 
affects all "lookup-like" functions when a prefix of the query matches 
only part of a shared prefix in the trie (e.g. looking for "fi" in a 
trie containing ["foo","bar","baz"], but not when looking up "fo", 
"food", or "bag").


* By popular demand Trie now has a Binary instance. This adds a new 
dependency on the binary package. The dependency shouldn't be onerous to 
anyone, but let me know if it is.




-- Links


Homepage:
http://code.haskell.org/~wren/

Hackage:

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bytestring-trie

Darcs:
http://code.haskell.org/~wren/bytestring-trie/

Haddock (Darcs version):

http://code.haskell.org/~wren/bytestring-trie/dist/doc/html/bytestring-trie/

--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Use of abbreviations in Haskell

2009-01-03 Thread Isaac Dupree
Ketil Malde wrote:
> A module may be defined in a file with a name corresponding to the
> module name, or any dot-separated prefix of it?  I.e. the file
> Foo/Bar.hs will define module Foo.Bar and optionally Foo.Bar.Baz as
> well?
>
> GHC should then be able to find it, and I believe it already has a
> prioritized search mechanism (presumably, the file could be named
> Foo.Bar.hs, too).

I don't think GHC actually allows that (Foo.Bar.hs, ever). But your suggestion 
could work.

1. Try Foo/Bar/Baz.hs ; if it exists, end search (and error if it does not 
contain Foo.Bar.Baz, obviously as the file's top-level module).
2. Try Foo.Bar.hs ; if it exists, end search (and error if it does not contain 
Foo.Bar.Baz, obviously as a sub-module).
3. Try Foo.hs ; if it exists, end search (and error if it does not contain 
Foo.Bar.Baz, obviously as a sub-module... or possibly as a sub-sub-module?).
4. give up :-)

Note though, that local modules tempt us to a couple other things too, even 
though they're not necessary to the proposal and would complicate it:
- access-controlled modules (e.g. if other code can't import Foo.Bar.Baz)
- relative-path imports / module names (e.g. if in Foo/Bar.hs we make Baz and 
try to import it some way with "import Baz")

and as we already mentioned, it would likely involve some implicit importing 
of the sub-module.

translating into ordinary haskell:
I think my module-search mechanism makes a well-defined, deterministic way to 
find the right module, no complex translation necessary (except layout rule 
madness maybe?).
Implicit importing: submodule syntax implies adding an "import 
The.Module.Name" line at that point in the containing file.  This would suggest 
that submodules must be at the top, among the imports, because all imports 
must syntactically be at the beginning of the file -- and there's a reason for 
this.  Bother!  Even if the reason is dependency chasing, one would think 
same-file dependencies aren't important, but the submodules themselves can 
import things from other files, so those lines should need to be near the 
beginning anyway.

so an example could be

module MyData
(
module MyData.Sub,  -- or equivalently, D(..)
transform
)
where

module MyData.Sub  --or "module Sub" ?? that seems a bit too ad-hoc though
where
  data D = E | F

transform :: D -> D
transform F = E
transform E = F


~Isaac

___
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-03 Thread Luke Palmer
2009/1/3 Xie Hanjian 

> Hi,
>
> I tried this in ghci:
> >Prelude> 1:2:[] == 1:2:[]
> True
>
> Does this mean (:) return the same object on same input,


Also, in functional programming, *every* function returns the same output
for the same input.  That's part of the definition of function.  :-)

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


[Haskell-cafe] teaching functional programming at work

2009-01-03 Thread Warren Harris
I am seeking suggestions from the haskell cafe for teaching functional  
programming concepts to colleagues at work. I'm currently working on a  
project using ocaml and functional programming techniques, and am a  
lone ranger at my workplace when it comes to this sort of thing (we  
are primarily a python shop). However there seems to be a growing  
curiosity in functional programming, and I think there's a lot to be  
learned from from it whether one chooses a functional language for  
their next big project or not.


But I'm a practitioner, not an academic or lecturer, and although I  
find the idea of helping my colleagues understand these concepts to be  
an exciting prospect, I'm not really sure where to start in terms of  
materials or overall direction. My sense is to form a study group  
(perhaps going through Real World Haskell together), but I'm a little  
afraid of assembling people together for a "now what?" experience. So  
my first question is whether this is even a good idea?


Some things I think would be useful to get across are:

- fp is more than just an exercise in avoiding assignment statements  
-- why a smart programmer should care?
- reading knowledge of ocaml and/or haskell (even syntax, precedence  
and infix operators can be an initial stumbling block)
- core concepts: type classes, proper tail recursion, higher-order  
functions, folds, combinators, monads, monad transformers, arrows
- evidence that concise expression can lead to less bugs / better  
maintainability (hard to prove, but perhaps a sense can be conveyed)
- relationship between types / theorems / programs / proofs and why  
this is important for the future of software


Regarding this last point, my own sense has been that by leveraging a  
powerful type system such as found in ocaml or haskell has allowed me  
to achieve things I never would have been able to without it (or at  
least would have ended up with a much less elegant implementation and  
much more debugging) but many seem to find types to be either an  
impedance to getting things done quickly, or at best irrelevant. I  
know this is for the most part a religious war, but I would like my  
colleagues to arrive at their opinion from an informed perspective,  
which means learning that there's more to typeful programming than  
what is presented by java or c++.


Finally, any comments on how to make the learning experience fun,  
engaging, and a positive experience would be greatly appreciated.


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


Re: [Haskell-cafe] Type Family Relations

2009-01-03 Thread Iavor Diatchki
Hello,
Usually, you can program such things by using super-classes.  Here is
how you could encode your example:

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

class HeaderOf addr hdr | addr -> hdr
class HeaderOf addr hdr => AddressOf hdr addr | addr -> hdr

data IPv4Header = C1
data IPv4   = C2
data AppAddress = C3
data AppHeader  = C4

instance AddressOf IPv4Header IPv4
instance HeaderOf IPv4 IPv4Header

{- results in error:
instance AddressOf AppHeader AppAddress
instance HeaderOf AppAddress [AppHeader]
-}

Hope that this helps,
Iavor



On Sat, Jan 3, 2009 at 7:22 AM, Thomas DuBuisson
 wrote:
> Cafe,
> I am wondering if there is a way to enforce compile time checking of
> an axiom relating two separate type families.
>
> Mandatory contrived example:
>
>> type family AddressOf h
>> type family HeaderOf a
>>
>> -- I'm looking for something to the effect of:
>> type axiom HeaderOf (AddressOf x) ~ x
>>
>> -- Valid:
>> type instance AddressOf IPv4Header = IPv4
>> type instance HeaderOf IPv4 = IPv4Header
>>
>> -- Invalid
>> type instance AddressOf AppHeader = AppAddress
>> type instance HeaderOf AppAddress = [AppHeader]
>
> So this is  a universally enforced type equivalence.  The stipulation
> could be arbitrarily complex, checked at compile time, and must hold
> for all instances of either type family.
>
> Am I making this too hard?  Is there already a solution I'm missing?
>
> Cheers,
> Tom
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Type Family Relations

2009-01-03 Thread Ryan Ingram
I've been fighting this same problem for a while.  The solution I've
come up with is to encode the axioms into a typeclass which gives you
a proof of the axioms.

Here's an excerpt from some code I've been playing around with; HaskTy
and Lift are type families.

-- Theorem: for all t instance of Lift, (forall env. HaskTy (Lift t) env == t)
data HaskTy_Lift_Id t env = (t ~ HaskTy (Lift t) env) => HaskTy_Lift_Id

class Thm_HaskTy_Lift_Id t where
thm_haskty_lift_id :: forall env. HaskTy_Lift_Id t env

instance Thm_HaskTy_Lift_Id Int where
thm_haskty_lift_id = HaskTy_Lift_Id
instance Thm_HaskTy_Lift_Id Bool where
thm_haskty_lift_id = HaskTy_Lift_Id

lemma_haskty_lift_id_app :: HaskTy_Lift_Id a env -> HaskTy_Lift_Id b
env -> HaskTy_Lift_Id (a -> b) env
lemma_haskty_lift_id_app HaskTy_Lift_Id HaskTy_Lift_Id = HaskTy_Lift_Id

instance (Thm_HaskTy_Lift_Id a, Thm_HaskTy_Lift_Id b)
=> Thm_HaskTy_Lift_Id (a -> b) where
thm_haskty_lift_id = lemma_haskty_lift_id_app thm_haskty_lift_id
thm_haskty_lift_id

As you can see, I encode a witness of the type equality into a
concrete data type.  You then direct the typechecker as to how to
prove the type equality using the typeclass mechanism; the class
instances closely mirror the type family instances.

You then add this typeclass as a context on functions that require the equality.

Control.Coroutine[1] uses a similar restriction:

class Connect s where
connect :: (s ~ Dual c, c ~ Dual s) => InSession s a -> InSession
c b -> (a,b)

A cleaner solution, that sadly doesn't work in GHC6.10 [2], would be
something like:

class (s ~ Dual (Dual s)) => Connect s where
connect :: InSession s a -> InSession (Dual s) b -> (a,b)

The difference is mainly one of efficiency; even though there is only
one constructor for Thm_HaskTy_Lift_Id t env, at runtime the code
still has to prove that evaluation terminates (to avoid _|_ giving an
unsound proof of type equality).   This means that deeply nested
instances of the (a -> b) instance require calling dictionary
constructors to match the tree, until eventually we see that each leaf
is a valid constructor.  If the type equality could be brought into
scope by just bringing the typeclass into scope, the dictionaries
themselves could remain unevaluated at runtime.

  -- ryan

[1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coroutine
[2] http://hackage.haskell.org/trac/ghc/ticket/2102

On Sat, Jan 3, 2009 at 7:22 AM, Thomas DuBuisson
 wrote:
> Cafe,
> I am wondering if there is a way to enforce compile time checking of
> an axiom relating two separate type families.
>
> Mandatory contrived example:
>
>> type family AddressOf h
>> type family HeaderOf a
>>
>> -- I'm looking for something to the effect of:
>> type axiom HeaderOf (AddressOf x) ~ x
>>
>> -- Valid:
>> type instance AddressOf IPv4Header = IPv4
>> type instance HeaderOf IPv4 = IPv4Header
>>
>> -- Invalid
>> type instance AddressOf AppHeader = AppAddress
>> type instance HeaderOf AppAddress = [AppHeader]
>
> So this is  a universally enforced type equivalence.  The stipulation
> could be arbitrarily complex, checked at compile time, and must hold
> for all instances of either type family.
>
> Am I making this too hard?  Is there already a solution I'm missing?
>
> Cheers,
> Tom
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: [Haskell] #haskell IRC channel reaches 600 users

2009-01-03 Thread Henk-Jan van Tuyl

On Fri, 02 Jan 2009 21:27:24 +0100, Don Stewart  wrote:



A small announcement :)

7 years after its inception, under the guiding hand of Shae Erisson (aka
shapr), the #haskell IRC channel[1] on freenode has reached 600
concurrent users! It's now in the top 3 language channels by size.



Some more statistics can be found at
  http://www.langpop.com/

An interesting quote from this site:
  It's interesting to note how languages like Haskell and Erlang
  are talked about a lot, despite scoring fairly low on the
  normalized popularity chart above. People are interested in
  them, but haven't begun to use them on a large scale yet.

We have to create more webpages about Haskell (containing the words
"programming" and "Haskell") to score better! :) And there should be
more Haskell jobs :)

Other sites with statistics:
  http://www.tiobe.com/content/paperinfo/tpci/index.html
  http://www.complang.tuwien.ac.at/anton/comp.lang-statistics/

An article about what makes a language popular:
  http://www.paulgraham.com/popular.html

--
Regards,
Henk-Jan van Tuyl


--
http://functor.bamikanarie.com
http://Van.Tuyl.eu/
--


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


[Haskell-cafe] Re: Pattern combinators

2009-01-03 Thread Massimiliano Gubinelli
David Menendez  zednenem.com> writes:

> 
> On Sun, Dec 21, 2008 at 10:14 PM, Andrew Wagner 
>  gmail.com> wrote:
> > I'd love to see a copy of this go up on hackage for experimentation.
>>  Would
> > you care to upload your code, or send it to me so I can upload it?
> 
> I've uploaded my latest version to . It
> explicitly makes patterns polymorphic over the answer type of the case
> statement by making Pattern a newtype and universally quantifying the
> (un)currying and matching functions.
> 
> For example,
> 
> (->>) :: Pattern a () vec -> Curry vec ans -> Case a ans
> 
> I'm not sure it makes sense to create a package just yet. At the very
> least, you should ask Morten Rhiger first. The type signatures are
> mine, but the code is mostly straight transcriptions from his paper.
> 

Hi,
 I've tried to undestand the paper, in particular the relation between
the combinators written in cps style and combinators written using a  
Maybe type (i.e pattern matching functions returning Maybe to signal 
success or failure). The code below gives an implementation of the 
basic pattern matching functions on top of two possible implementation 
of an abstract interface for building and using bindings. In particular 
using type families it seems to be possible to automatically construct a 
function inj to convert between a function in the form a->b->c->d to a 
function in the form (a,(b,c,())) -> d,  thereby removing the need of 
building such coverter via the pattern matching functions like suggested 
in the paper.

Since I'm an Haskell begineer I would appreciate very much comments or 
suggestions for improvements.

Best,
Massimiliano Gubinelli

Here the code:
---
{-# LANGUAGE  TypeFamilies, MultiParamTypeClasses, 
 FlexibleInstances,  RankNTypes  #-}
  
module PM where

-- inj converts a function of the form a -> b -> c -> d to the
-- uniform representation (a,(b,(c,( -> d 

class Fn a c where
type Fnq a c
inj :: Fnq a c -> a -> c

instance Fn () c where
type Fnq () c = c
inj f () = f 

instance Fn b c => Fn (a,b) c where
type Fnq (a,b) c = a -> Fnq b c
inj f (a,b) = inj (f a) b


-- pattern matching, cps style
-- a binding function has three inputs: ks kf v. v is a list of 
-- current bindings.

newtype PatA a b = PatA {
  unPatA :: forall ans. (b -> ans) -> ans -> a -> ans 
  }

applyA :: PatA a b -> (b -> c) -> c -> a -> c
applyA (PatA p) ks kf v = p ks kf v

meetA :: PatA a b -> PatA b c  -> PatA a c 
meetA (PatA a) (PatA b) =  PatA $ \ ks kf -> a (b ks kf) kf

joinA :: PatA a b -> PatA a b  -> PatA a b 
joinA (PatA a) (PatA b) = PatA $ \ ks kf v -> a ks (b ks kf v) v

anyA :: PatA a a 
anyA  = PatA $ \ ks kf -> ks

noneA :: PatA a a 
noneA = PatA $ \ ks kf v -> kf

varA :: x -> PatA a (x,a) 
varA x = PatA $ \ ks kf v -> ks (x,v)

pairA a b (x,y) = meetA (a x) (b y)
conA a x = if a == x then  anyA   else  noneA
andA a b x = meetA (a x) (b x)
orA p n x = joinA (p x) (n x)   

matchA val pat = pat val ()
caseA a fa fb x v = applyA (a x) (inj fa) (fb x v) v
otherwiseA kf = \x v -> kf


isA p x = matchA x $ caseA p (\_ -> True) $ otherwiseA False


testA1 z  =  matchA z $ caseA (conA (1,2)) ("first match") $
caseA (pairA (conA 1) varA) 
  (\x -> "second match " ++ show x) $
caseA (pairA varA varA)
  (\x y -> "third match " ++ show x) $
otherwiseA "mismatch" 




-- pattern matching, Maybe style

-- a binding function receives a list of current bindings and returns
-- a Maybe type containing the list of updated bindings in case of 
-- success

newtype PatB a b = PatB { unPatB :: a -> Maybe b }

applyB :: PatB a b -> (b -> c) -> c -> a -> c
applyB (PatB p) ks kf v = maybe kf ks (p v)

meetB :: PatB a b -> PatB c a -> PatB c b
meetB (PatB a) (PatB b) = PatB $ \v -> (b v) >>= a

joinB :: PatB a b -> PatB a b -> PatB a b
joinB (PatB a)  (PatB b) = PatB $ \v -> maybe (b v) Just (a v)

anyB :: PatB a a
anyB = PatB $ \v -> Just v

noneB :: PatB a a
noneB = PatB $ \v -> Nothing

varB :: x -> PatB a (x,a)
varB x = PatB $ \v -> Just (x,v)


pairB a b (x,y) =  meetB (a x) (b y)
conB a x = if a == x then  anyB  else noneB
orB a b x = joinB (a x) (b x)
andB a b x = meetB (a x) (b x)

matchB val pat = pat val ()

--caseB a fa fb x v = maybe (fb x v) (inj fa) ((unPatB $ a x) v) 
caseB a fa fb x v = applyB (a x) (inj fa) (fb x v) v
otherwiseB f = \x v -> f

isB p x = matchB x $ caseB p (\_ -> True) $ otherwiseB False

testB1 z = matchB z $ caseB (pairB (conB 1) (conB 2)) ("first match") $
caseB (pairB (conB 1) varB) (\x -> "second match " ++ show x) $
caseB (pairB varB varB) (\x y -> "third match " ++ show x) $
otherwiseB "mismatch"





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


Re: [Haskell-cafe] Re: How do we decide on the new logo?

2009-01-03 Thread Eelco Lempsink

On 3 jan 2009, at 17:33, Sebastian Sylvan wrote:

On Sat, Jan 3, 2009 at 3:15 AM,  wrote:

On Sat, 3 Jan 2009, Achim Schneider wrote:


Step 2: Determine the winner by polling preferences, same-level
preference (ambivalence) allowed
(eg. place 1 for logos C and D, place 2 for A and place 3 for B)


The only reasonable method of voting using this ranking data is one  
of the Condorcet methods.  How you break ties doesnt matter much to  
me. Wikimedia, Debian, Gentoo, and Software in the Public Intrest  
all use Schulze method for what that is worth.


Yes. Condorcet voting picks the best compromise and is IMO the way  
to do this - we won't all agree on the best logo, but at least we  
can pick the least disliked one.
It doesn't need to be super sophisticated, just a box next to each  
logo where you can enter a rank in any range you like (1 being most  
preferred, empty boxing being equivalent to +Inf), allowing multiple  
entries to share the same rank.



Since there already is a condorcet voting package on Hackage, I made a  
simple (HAppS powered) web app where you can drag-n-drop your  
preferences.  See http://github.com/eelco/voting/tree/master for the  
code (contributions more than welcome! Note, there's also a jQuery  
branch which has a bit different drag-n-drop behaviour) and http://code.tupil.com/voting/ 
 for a live demo.


It needs a bit more work but mainly a whole bulk of decisions, like
* Limit voting, if so how?  Email confirmation, IP based, vote once,  
once per day?

* Maybe don't show the results until the contest is over?

I, for one, very much welcome any benevolent dictator to make these  
decisions, because we can probably argue about pros and cons for  
months.  Since Don started the contest (http://www.haskell.org/pipermail/haskell-cafe/2008-December/051836.html 
) and also seems to have some ideas about the voting process (http://www.haskell.org/pipermail/haskell-cafe/2008-December/052257.html 
), I hereby officially appoint him to lead to masses.  (Does it work  
like that? ;)


--
Regards,

Eelco Lempsink



PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Use of abbreviations in Haskell

2009-01-03 Thread Ketil Malde
Isaac Dupree  writes:


> Derek Elkins wrote:
>> I haven't been able to find any semantic difficulties with this
>> addition.

> I like it too... what I run into is that there's an implicit
> assumption that module of name Foo.Bar.Baz *must* be found in a file
> Foo/Bar/Baz.[l]hs . 

Ah, surely mere practicalities will not stand in the way of improving
the usability of the language?

> GHC uses this all the time

..unless you want a compiler, I guess.  How about this:

A module may be defined in a file with a name corresponding to the
module name, or any dot-separated prefix of it?  I.e. the file
Foo/Bar.hs will define module Foo.Bar and optionally Foo.Bar.Baz as
well? 

GHC should then be able to find it, and I believe it already has a
prioritized search mechanism (presumably, the file could be named
Foo.Bar.hs, too).  

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] [ANN] Haskell web server + wiki: salvia-0.0.4 + orchid-0.0.6

2009-01-03 Thread Gwern Branwen
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

On Thu, Jan 1, 2009 at 9:04 AM, Sebastiaan Visser  wrote:
> Happy new year, you all!
>
> I'm pleased to announce three new packages on Hackage:

> I had some trouble getting all dependencies right on systems other than my
> own. Using `cabal install' seems to behave differently from `./Setup
> install' in the package directory, but this may vary from system to system.
> It is known to work at least on Macosx and Linux with GHC 6.8, 6.10 or even
> 6.11. Pdflatex is needed for PDF generation, dvipng for inline formulas.
>
> Have fun and best wishes for this new year!
>
>
> [1] http://funct.org/wiki/
> [2] http://funct.org/wiki/data/Index.html
> [3] http://www.cs.uu.nl/wiki/HUT/AttributeGrammarSystem

Sebastiaan: are there any public repos for these packages?

- --
gwern
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAklfryAACgkQvpDo5Pfl1oJuIACdHtzspXuAt3Bp4UXAubvT0UvD
RtkAn1PlqWYbAxLRG4WOqAmZw6Dd6f/1
=wwLT
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Haskell Weekly News: Issue 99 - January 3, 2009

2009-01-03 Thread Brent Yorgey
---
Haskell Weekly News
http://sequence.complete.org/hwn/20090103
Issue 99 - January 03, 2009
---

   Welcome to issue 99 of HWN, a newsletter covering developments in the
   [1]Haskell community.

   Happy new year to all! May 2009 be a year full of joy, family, friends,
   professional success, much Haskell hacking, and a minimal number of
   rabid weasels. Just in case.

Announcements

   #haskell IRC channel reaches 600 users. Don Stewart [2]announced that 7
   years after its inception, under the guiding hand of Shae Erisson (aka
   shapr), the [3]#haskell IRC channel on freenode has reached 600
   concurrent users!

   citeproc-hs-0.2. andrea rossato [4]announced the release of
   [5]citeproc-hs-0.2, a Haskell implementation of the Citation Style
   Language, which adds a Bibtex like citation and bibliographic
   formatting and generation facility to [6]pandoc. This version adds
   support for citation collapsing, a wrapper around [7]hs-bibutils, and
   some [8]API documentation.

   hs-bibutils-0.1. andrea rossato [9]announced the first release of
   [10]hs-bibutils, Haskell bindings to Chris Putnam's [11]bibutils.
   Bibutils is a library and a set of bibliographic utilities to
   interconvert between various bibliography database formats using a
   common MODS-format XML intermediate.

   Haskell koans. Gwern Branwen [12]issued an RFK (Request for [13]Koans),
   following the success of his CFH (Call for [14]Haiku).

   [ANN] Haskell web server + wiki: salvia-0.0.4 + orchid-0.0.6.
   Sebastiaan Visser [15]announced the release of three new packages:
   [16]salvia, a lightweight modular web server framework; [17]orchid,
   a(nother) wiki written in Haskell, using Darcs as a versioning back-end
   and Salvia as the application server; and [18]orchid-demo, a simple
   demo application using Salvia and Orchid to serve an example darcs
   repository. You can play around with an [19]online demo.

   gitit-0.4.1, recaptcha-0.1. John MacFarlane [20]announced the release
   of [21]gitit-0.4.1, a wiki program that stores pages in a git
   repository. This release adds support for (optional) captchas, using
   the reCAPTCHA service. The reCAPTCHA code has been packaged as a
   separate library on Hackage, [22]recaptcha.

   monte-carlo-0.2, gsl-random-0.2.3. Patrick Perry [23]announced the
   release of a new version of the [24]monte-carlo package. The new
   version includes a more general type class, MonadMC, which allows all
   the functions to work in both MC and MCT monads; functions to sample
   from discrete distributions, and functions to sample subsets. There is
   also a [25]quick tutorial.

   Reading group for Programming Collective Intelligence. Creighton Hogg
   [26]announced that he would like to start a small group for the
   O'Reilly book [27]Programming Collective Intelligence, to work through
   translating some of the examples to Haskell. Email Creighton if you are
   interested in participating.

   Maintaining laziness. Henning Thielemann [28]announced that he has
   written a [29]tutorial on how to make functions lazy and how to test
   whether they are actually lazy.

   Request for feedback: Understanding Haskell Monads. Ertugrul Soeylemez
   [30]requested feedback on a new [31]monad tutorial.

Discussion

   How do we decide on the new logo?. Fritz Ruehr began a [32]discussion
   of how to go about choosing a winner of the [33]Great 2009 Haskell Logo
   Contest. Weigh in if you care!

Jobs

   Two Positions as Associate Professor in Software Engineering at
   Chalmers University. Koen Claessen [34]announced the availability of
   [35]two positions as Associate Professor at Chalmers University in
   Gothenburg, Sweden, within the division of Software Engineering and
   Technology at the department of Computer Science and Engineering. The
   application deadline is January 12, 2009.

Blog noise

   [36]Haskell news from the [37]blogosphere.
 * GHC / OpenSPARC Project: [38]Bootstrapping.
 * Dan Piponi (sigfpe): [39]Rewriting Monadic Expressions with
   Template Haskell.
 * GHC / OpenSPARC Project: [40]Fighting dependencies.
 * GHC / OpenSPARC Project: [41]A new year and a new project.
 * Alson Kemp: [42]2009: The Year Of Hackage.
 * Patrick Perry: [43]Monte Carlo Poker Odds.
 * Joachim Breitner: [44]Handling explicit and implicit recursion in
   Haskell data.
 * Luke Palmer: [45]Domain Convergence.
 * Eric Kow (kowey): [46]riot is almost a Haskell mail client.
 * John Goerzen (CosmicRay): [47]Real World Haskell update.
 * Alson Kemp: [48]A Plea For "cabal install".
 * Alson Kemp: [49]Cyptol on Slashdot.

Quotes of the Week

 * lilac:  how do I see the number of reductions required to
   calculate something?  bohdan: the usual method is to ask
   Cale 

Re: [Haskell-cafe] Type Family Relations

2009-01-03 Thread Austin Seipp
Excerpts from Thomas M. DuBuisson's message of Sat Jan 03 09:22:47 -0600 2009:
> Mandatory contrived example:
> 
> > type family AddressOf h
> > type family HeaderOf a
> >
> > -- I'm looking for something to the effect of:
> > type axiom HeaderOf (AddressOf x) ~ x
> >
> > -- Valid:
> > type instance AddressOf IPv4Header = IPv4
> > type instance HeaderOf IPv4 = IPv4Header
> >
> > -- Invalid
> > type instance AddressOf AppHeader = AppAddress
> > type instance HeaderOf AppAddress = [AppHeader]
> 
> So this is  a universally enforced type equivalence.  The stipulation
> could be arbitrarily complex, checked at compile time, and must hold
> for all instances of either type family.
> 
> Am I making this too hard?  Is there already a solution I'm missing?
> 

The problem is that type classes are open - anybody can
extend this family i.e.

> type instance AddressOf IPv4Header = IPv4
> type instance HeaderOf IPv4 = IPv4Header
> type instance AddressOf IPv6Header = IPv4
>
> ipv4func :: (AddressOf x ~ IPv4) => x -> ...

And it will perfectly accept arguments with a type of IPv6Header.

There is a proposal for extending GHC to support type invariants of
this nature, but it is not implemented:

  http://tomschrijvers.blogspot.com/2008/11/type-invariants-for-haskell.html

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


Re: [Haskell-cafe] databases in Haskell & type-safety

2009-01-03 Thread brian
On Sat, Jan 3, 2009 at 4:25 AM, Austin Seipp  wrote:
> NB: I have *just* (about 5 minutes ago) sent in a patch for takusen
> to get it to build on GHC 6.10.1 to Oleg. Hopefully an updated version
> will appear on hackage in the next few days.

Yay! Thanks. I've been waiting.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: How do we decide on the new logo?

2009-01-03 Thread Sebastian Sylvan
On Sat, Jan 3, 2009 at 3:15 AM,  wrote:

> On Sat, 3 Jan 2009, Achim Schneider wrote:
>
>  Step 2: Determine the winner by polling preferences, same-level
>> preference (ambivalence) allowed
>> (eg. place 1 for logos C and D, place 2 for A and place 3 for B)
>>
>
> The only reasonable method of voting using this ranking data is one of the
> Condorcet methods.  How you break ties doesnt matter much to me. Wikimedia,
> Debian, Gentoo, and Software in the Public Intrest all use Schulze method
> for what that is worth.
>

Yes. Condorcet voting picks the best compromise and is IMO the way to do
this - we won't all agree on the best logo, but at least we can pick the
least disliked one. It doesn't need to be super sophisticated, just a box
next to each logo where you can enter a rank in any range you like (1 being
most preferred, empty boxing being equivalent to +Inf),
allowing multiple entries to share the same rank.

-- 
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
___
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-03 Thread Xie Hanjian
Thanks guys :-)

* Nicolas Pouillard  [2009-01-03 16:39:59 +0100]:

> Excerpts from Xie Hanjian's message of Sat Jan 03 16:28:30 +0100 2009:
> > Hi,
> > 
> > I tried this in ghci:
> > >Prelude> 1:2:[] == 1:2:[]
> > True
> > 
> > Does this mean (:) return the same object on same input, or
> > (==) is not for identity checking? If the later is true, how
> > can I check two object is the *same* object?
> 
> Here (==) is the structural equality. There is generally no exposed function
> to check for identity of values. This would expose too much of the memory
> model and the compilation process to give a specification to such a function.
> 
> -- 
> Nicolas Pouillard

-- 
jan=callcc{|jan|jan};jan.call(jan)


pgpgPJ9sBZB8C.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2009-01-03 Thread Günther Schmidt

Hi Jan,

in functional programming there is no such thing as "identity" as we  
understand the idea from OO.


There is only such as thing as "equality" though.

Günther


Am 03.01.2009, 16:28 Uhr, schrieb Xie Hanjian :


Hi,

I tried this in ghci:

Prelude> 1:2:[] == 1:2:[]

True

Does this mean (:) return the same object on same input, or
(==) is not for identity checking? If the later is true, how
can I check two object is the *same* object?

Thanks
Jan





--
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/

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


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

2009-01-03 Thread Xie Hanjian
Hi,

I tried this in ghci:
>Prelude> 1:2:[] == 1:2:[]
True

Does this mean (:) return the same object on same input, or
(==) is not for identity checking? If the later is true, how
can I check two object is the *same* object?

Thanks
Jan

-- 
jan=callcc{|jan|jan};jan.call(jan)


pgpJa3i8YUIrV.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Type Family Relations

2009-01-03 Thread Thomas DuBuisson
Cafe,
I am wondering if there is a way to enforce compile time checking of
an axiom relating two separate type families.

Mandatory contrived example:

> type family AddressOf h
> type family HeaderOf a
>
> -- I'm looking for something to the effect of:
> type axiom HeaderOf (AddressOf x) ~ x
>
> -- Valid:
> type instance AddressOf IPv4Header = IPv4
> type instance HeaderOf IPv4 = IPv4Header
>
> -- Invalid
> type instance AddressOf AppHeader = AppAddress
> type instance HeaderOf AppAddress = [AppHeader]

So this is  a universally enforced type equivalence.  The stipulation
could be arbitrarily complex, checked at compile time, and must hold
for all instances of either type family.

Am I making this too hard?  Is there already a solution I'm missing?

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


Re: [Haskell-cafe] Re: How do we decide on the new logo?

2009-01-03 Thread Richard Kelsall

Achim Schneider wrote:
...

Step 3: Re-open contest, accepting submissions _using_ the winning
logo, in the categories a) colour schemes[1] b), official shapes[2] c),
font[3] to go to b), d) layouts of b) + c)

...

This is a good suggestion. I would like small adjustments to the logo
to be possible before it's frozen. Some kind of Step 3 will result
in a much better logo. For example, I really like the pyramid from
above / square containing three triangles that Lenny222 submitted, but
I wouldn't choose this precise colour scheme and form. I didn't have
time to enter an alternative. When the field has been significantly
reduced I think people will be willing to expend effort improving the
remaining entries.


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


Re: [Haskell-cafe] unsafeInterleaveIO respecting order of actions

2009-01-03 Thread Henning Thielemann


On Sat, 3 Jan 2009, Henning Thielemann wrote:


On Thu, 1 Jan 2009, Brandon S. Allbery KF8NH wrote:


On 2009 Jan 1, at 16:44, Henning Thielemann wrote:

If it is generally possible to use unsafeInterleaveIO such that it
executes actions in the right order, wouldn't this allow the definition
of a general lazy IO monad?


I thought unsafeInterleaveIO and users of it (readFile, hGetContents) 
didn't guarantee the order of actions relative to independent IO actions 
(that is, those performed outside the unsafeInterleaveIO) and this was why 
it is generally disrecommended.  For example the recurring situation where 
people try to readFile f >>= writeFile . someTransform and the writeFile 
fails with a "file locked" exception.


Sure, it's dangerous. But for what I want to do, this situation cannot occur. 
I can come up with a simple example which might be generalized. It simulates 
what hGetContents does.


liftLazy2 :: (a -> b -> c) -> IO a -> IO b -> IO c
liftLazy2 f x y =
  fmap (\ ~(xr, ~(yr,())) -> f xr yr) $
  unsafeInterleaveIO $ liftM2 (,) x $
  unsafeInterleaveIO $ liftM2 (,) y $
  return ()


I think I now have general Applicative functionality:


apply :: (a -> b, ()) -> (a,()) -> (b,())
apply (f,fs) a =
   let (a0,as) = case fs of () -> a
   in  (f a0, as)

lazyIO :: IO a -> IO (a,())
lazyIO = unsafeInterleaveIO . fmap (\x -> (x,()))


liftLazy2 :: (a -> b -> c) -> IO a -> IO b -> IO c
liftLazy2 f x y =
   liftM2
  (\xr yr -> fst $ (f,()) `apply` xr `apply` yr)
  (lazyIO x) (lazyIO y)


The () is used to enforce the order of evaluation.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Updating doubly linked lists

2009-01-03 Thread Niklas Broberg
> Is it possible to change a particular node of the
> doubly linked list? That is to say, that would like
> to have a function:
> update :: DList a -> a -> DList a
> where
> update node newValue
> returns a list where only the value at the node
> which is passed in is set to the new Value and
> all other values are the same.

What you need is for the nodes to keep track of the length of the
list. Here's a different solution from that oleg posted, to me it's
slightly more intuitive, since the updates work directly on the dlists
instead of via (elegant) proxy functions.

--
module DList where

data DList a
= DNode Int (DList a) a (DList a)
| Empty

mkDList :: [a] -> DList a
mkDList [] = Empty
mkDList xs =
let len = length xs
this = DNode len farLeft (head xs) nearRight
(nearRight,farLeft) = mkRestDList len (tail xs) this this
 in this

mkRestDList :: Int -> [a] -> DList a -> DList a -> (DList a, DList a)
mkRestDList _ []  _ farRight =
(farRight, farRight) -- will only happen if the initial list is singleton
mkRestDList len [x] nearLeft farRight =
let this = DNode len nearLeft x farRight
 in (this, this)
mkRestDList len (x:xs) nearLeft farRight =
let this = DNode len nearLeft x nearRight
(nearRight,farLeft) = mkRestDList len xs this farRight
 in (this,farLeft)

takeD :: Int -> DList a -> [a]
takeD 0 _ = []
takeD _ Empty = []
takeD n (DNode _ _ x r) = x : takeD (n-1) r

leftD, rightD :: DList a -> DList a
leftD Empty = Empty
leftD (DNode _ l _ _) = l
rightD Empty = Empty
rightD (DNode _ _ _ r) = r

updateD :: a -> DList a -> DList a
updateD _ Empty = Empty
updateD x (DNode len _ _ r) =
let this = DNode len farLeft x nearRight
(nearRight,farLeft) = updateRestD (len-1) r this this
 in this

updateRestD :: Int -> DList a -> DList a -> DList a -> (DList a, DList a)
updateRestD 0 _ _ farRight =
(farRight, farRight) -- will only happen if the initial list is singleton
updateRestD 1 (DNode len _ x _) nearLeft farRight =
let this = DNode len nearLeft x farRight in (this, this)
updateRestD n (DNode len _ x r) nearLeft farRight =
let this = DNode len nearLeft x nearRight
(nearRight,farLeft) = updateRestD (n-1) r this farRight
 in (this,farLeft)
updateRestD _ Empty _ _ = undefined -- can't happen

-

*DList> let dl = mkDList [1..5]
*DList> takeD 11 dl
[1,2,3,4,5,1,2,3,4,5,1]
*DList> let dl' = updateD (-1) dl
*DList> takeD 11 dl'
[-1,2,3,4,5,-1,2,3,4,5,-1]

Cheers,

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


[Haskell-cafe] Re: databases in Haskell & type-safety

2009-01-03 Thread Gour
> "Austin" == Austin Seipp  writes:

Austin> Have you tried the simple sqlite3 bindings available?
Austin> http://hackage.haskell.org/cgi-bin/hackage-scripts/package/sqlite

Not (yet), but those are the one I mentioned (besides HDBC) under d) ;)

Austin> Takusen is based on the (unique) concept of a left-fold
Austin> enumerator. Having a left-fold interface guarantees timely
Austin> (nearly perfect, really) deallocation of resources while still
Austin> having the benefits of a 'lazy' stream. This interface has (as
Austin> shown by Oleg and others) proven to be very efficient in a
Austin> number of cases as well as favorable for many. The idea is very
Austin> novel, and truly worth exploring if you ask me.

Thank you very much. I went through the docs for which you provided some
references - I cannot claim I understood everything, but it sounds/looks
quite interesting and worth exploring.

Is there any simple tutorial about using Takusen available somewhere?

Austin> NB: I have *just* (about 5 minutes ago) sent in a patch for
Austin> takusen to get it to build on GHC 6.10.1 to Oleg. Hopefully an
Austin> updated version will appear on hackage in the next few days.

Great news!


Sincerely,
Gour

-- 

Gour  | Zagreb, Croatia  | GPG key: C6E7162D



pgpWbjHPU1bkV.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: databases in Haskell & type-safety

2009-01-03 Thread Gour
> "Henning" ==  writes:

Henning> No, it is maintained by frede...@ofb.net . I have also
Henning> contributed Oracle/OCI code a half year ago.

Oops, I stand corrected...nice to hear.

Still, it would be nice to present some info 'cause web site still shows
1.7 from Dec '05 as the latest release :-(


Sincerely,
Gour

-- 

Gour  | Zagreb, Croatia  | GPG key: C6E7162D



pgpb32PgU4X2z.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] databases in Haskell & type-safety

2009-01-03 Thread Henning Thielemann
Gour schrieb:
> Hi!
> 
> I'd like to use sqlite3 as application storage in my haskell project...
> 
> Browsing the available database options in Haskell it seems that:
> 
> a) HSQL is dead (hackage reports build-failure with 6.8 & 6.10)

No, it is maintained by frede...@ofb.net . I have also contributed
Oracle/OCI code a half year ago.

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


[Haskell-cafe] Re: Updating doubly linked lists

2009-01-03 Thread Apfelmus, Heinrich
S. Günther wrote:
>
>> What kind of structure do you need exactly?
>
> What I really need is a structure which represents a two dimensional 
> grid, i.e. it consists of nodes having a value and a list of
> neighbours attached to it. Point is that if node 1 has node 2 as a
> neighbour then node 2 has to have node 1 as a
> neighbour and each node has the same number of neighbours (currently
> 4, but may vary).

Ah, so you have a rectangular (or later hexagonal?) 2D grid? I suggest
representing it as

  Data.Map (Integer, Integer) a

as explained below.

> That's why I said that thinking about the circular case was just a
> divergence that really got me wondering/interested which is why I posted
> the question in it's short form at the beginning.

Exploring a related easier problem is always a good way to get some
intuition for tackling the harder one. :)

> Anyways, back to the structure I need. One additional thing which will
> happen during the algorithm is that there will be updates to a certain
> local neighboruhood of a node. Now I understand, that that might very
> well be possible with zippers.
>
> Instead of lists of neighbouring nodes I might as well save the paths
> through the graphs separately from the nodes although I only have a very
> vague intuition about how that would look like. And instead of calculating
> a lists of nodes to update, I could calculate a path visting the
> nodes and update them (again beeing unable to escape from the prison
> of an imperative mindset) traversing the path.

A zipper indeed allows you to move to neighbors and update them.

> But the point was that I just had a hard time generalizing what I read
> about zippers to structures where you can have embedded cycles, e.g.
>
> up . left . down . right = id.

If you interpret zippers as the original data structure with a hole,
this is not so difficult. For instance, consider a rectangular grid

  +--+--+--+--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+

where you store some data at every node. Now, a zipper is just the old
data structure but one node is marked as "hole"

  +--+--+--+--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--O--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+
  |  |  |  |  |  |  |  |
  +--+--+--+--+--+--+--+

If you represent the grid as a rectangular table

  type Position = (Integer, Integer)
  type Grid a   = Data.Map Position a

a zipper is simply the grid with an extra marker

  type Zipper a = (Grid a, Position)

  left,right,up,down :: Zipper a -> Zipper a
  left  (g,(x,y)) = (g,(x-1,y))
  right (g,(x,y)) = (g,(x+1,y))
  up(g,(x,y)) = (g,(x,y-1))
  down  (g,(x,y)) = (g,(x,y+1))

  update :: a -> Zipper a -> Zipper a
  update a (g,(x,y)) = (insert (x,y) a g, (x,y))

Note that the  left, right  etc. are not "baked into" the data type but
implemented as normal functions.

In principle, the same could be done for lists

  type ZipperL a = ([a], Int)

  left, right :: ZipperL a -> ZipperL a
  left  (xs,i) = (xs,i-1)
  right (xs,i) = (xs,i+1)

  update :: a -> ZipperL a -> ZipperL a
  update a (xs,i) = (take i xs ++ [a] ++ drop (i+1) xs, i)

This is a valid implementation of a zipper for lists, but of course is
very inefficient,  update  is O(n) . The key thing about the original
list zipper with back and front list is that all operations are O(1).

For the 2D grid zipper above, moving around is O(1) but update is O(log
n). This is acceptable; also because I'm quite confident that a zipper
for a 2D grid with everything O(1) does not exist. I can prove that for
a special case and should probably write it down at some point.

In other words, I suggest representing your grid as a

   Data.Map (Integer,Integer) a

and accept the minor inconvenience of a O(log n) update. Choosing a
different finite map implementation may give a better constant factor.
For instance you can nest two  Data.IntMap  etc.


> Righty right, but there's still the possibility that given all the 
> time in the world and the clearest explanations I'm just to dense to
> get a hold of it. That said I hope that's not the case but I might
> still be better off timewise to just go with MVars and a
> straightforward way first and then doing the reading and
> maybe refactoring to a different approach.

My personal experience is that not going with the obvious but messy
solution but searching for a more elegant one is always faster in the
long run. :)


Regards,
H. Apfelmus

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


Re: [Haskell-cafe] unsafeInterleaveIO respecting order of actions

2009-01-03 Thread Henning Thielemann


On Thu, 1 Jan 2009, Brandon S. Allbery KF8NH wrote:


On 2009 Jan 1, at 16:44, Henning Thielemann wrote:

If it is generally possible to use unsafeInterleaveIO such that it
executes actions in the right order, wouldn't this allow the definition
of a general lazy IO monad?


I thought unsafeInterleaveIO and users of it (readFile, hGetContents) didn't 
guarantee the order of actions relative to independent IO actions (that is, 
those performed outside the unsafeInterleaveIO) and this was why it is 
generally disrecommended.  For example the recurring situation where people 
try to readFile f >>= writeFile . someTransform and the writeFile fails with 
a "file locked" exception.


Sure, it's dangerous. But for what I want to do, this situation cannot 
occur. I can come up with a simple example which might be generalized. It 
simulates what hGetContents does.


liftLazy2 :: (a -> b -> c) -> IO a -> IO b -> IO c
liftLazy2 f x y =
   fmap (\ ~(xr, ~(yr,())) -> f xr yr) $
   unsafeInterleaveIO $ liftM2 (,) x $
   unsafeInterleaveIO $ liftM2 (,) y $
   return ()

test0, test1 :: IO String
test0 = liftLazy2 (const)  getLine getLine
test1 = liftLazy2 (flip const) getLine getLine


test0 only requests the first line,
test1 expects two lines as user input.

However, with liftLazy2 we have only Applicative functionality, not Monad, 
and it is not composable.


For example:
  fmap (\((x,y),z) -> z) $ liftLazy2A (,) (liftLazy2A (,) getLine getLine) 
getLine

This requests only one line, but should three ones. The reason is that the 
first two getLines are defered even until the last one. Thus, it is not 
enough that liftLazy2 returns (IO c). Instead it must return (IO 
(c,(a,(b,() and these pair emulated lists must somehow be combined in 
order to preserve the order of execution. This looks somehow like a writer 
monad transformer.

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


Re: [Haskell-cafe] databases in Haskell & type-safety

2009-01-03 Thread Austin Seipp
Excerpts from Gour's message of Sat Jan 03 03:48:44 -0600 2009:
> Hi!
> 
> I'd like to use sqlite3 as application storage in my haskell project...
> 
> Browsing the available database options in Haskell it seems that:
> 
> a) HSQL is dead (hackage reports build-failure with 6.8 & 6.10)
> 
> b) haskelldb is also not in a good shape - build fails with 6.8 & 6.10
> 
> For Haskell-newbie as myself, it looks that haskelldb is the one which
> provide(ed)s the most secure API (I was reading draft paper about
> MetaHDBC but, apparently, the type inference support in open-source
> databases is poor and that's why, according to the author "This is
> unfortunately as it makes MetaHDBC a lot less valuable." 
> 
> What remains is:
> 
> c) Takusen which is also not up-to-date (it fails with 6.10) and
> 
> d) HDBC and sqlite bindings which are the only packages which build with
> 6.10.

Have you tried the simple sqlite3 bindings available?
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/sqlite

> I'm not familiar with Takusen which says: "Takusen's unique selling
> point is safety and efficiency..." and I would appreciate if someone
> could shed some more light to its 'safety' and the present status?

Takusen is based on the (unique) concept of a left-fold
enumerator. Having a left-fold interface guarantees timely (nearly
perfect, really) deallocation of resources while still having the
benefits of a 'lazy' stream. This interface has (as shown by Oleg and
others) proven to be very efficient in a number of cases as well as
favorable for many. The idea is very novel, and truly worth exploring
if you ask me.

For more information about left-fold enumerators and takusen, see here:

http://okmij.org/ftp/papers/LL3-collections-enumerators.txt
http://okmij.org/ftp/Haskell/fold-stream.lhs
http://okmij.org/ftp/Haskell/misc.html#takusen

NB: I have *just* (about 5 minutes ago) sent in a patch for takusen
to get it to build on GHC 6.10.1 to Oleg. Hopefully an updated version
will appear on hackage in the next few days.

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


[Haskell-cafe] Re: Updating doubly linked lists

2009-01-03 Thread oleg

Stephan Guenther wrote:

> Is it possible to change a particular node of the doubly linked list?
> That is to say, that would like to have a function:
> update :: DList a -> a -> DList a
> where
> update node newValue
> returns a list where only the value at the node which is passed in is
> set to the new Value and all other values are the same. All this of
> course in a pure way, that is without using (M/T/TM)Vars or IORefs.

It is possible to do all of this, and more:
- no rebuilding of the whole list on updates to the list
- the update operation takes constant time (for lists longer
  than 32 elements on 32-bit platform)
- both cyclic and terminated lists can be handled, uniformly
- no monads used or mentioned
- let alone no IORef, STRef, TVars, etc.

The algorithm is essentially imperative (and so permits identity
checking and in-place `updates') but implemented purely
functionally. No destructive updates are ever used. Therefore, all the
changes can be undone and re-done, and the code is MT-safe. The code
is easily generalizable to 2D.

Here are the tests

> testl = fromList [1..5]
> testl_s = takeDL 11 testl

*FL> testl_s
[5,1,2,3,4,5,1,2,3,4,5]

> testl1 = update (-1) testl
> testl1_s = takeDL 11 testl1
*FL> testl1_s
[-1,1,2,3,4,-1,1,2,3,4,-1]

> testl2 = update (-2) . move_right' . move_right' $ testl1
> testl2_s = takeDL 11 testl2
*FL> testl2_s
[-2,3,4,-1,1,-2,3,4,-1,1,-2]

> -- Old testl is still available
> testl3 = update (-2) . move_right' . move_right' $ testl
> testl3_s = takeDL 11 testl3
*FL> testl3_s
[-2,3,4,5,1,-2,3,4,5,1,-2]


It is not for nothing Haskell is called the best imperative
language. One can implement imperative algorithms just as they are --
purely functionally, without any monads or other categorical notions.


module FL where

import qualified Data.IntMap as IM

-- Representation of the double-linked list

type Ref = Int  -- positive, we shall treat 0 specially

data Node a = Node{node_val   :: a,
   node_left  :: Ref,
   node_right :: Ref}

data DList a = DList{dl_counter :: Ref, -- to generate new Refs
 dl_current :: Ref, -- current node
 dl_mem :: IM.IntMap (Node a)} -- main `memory'

-- Operations on the DList a

empty :: DList a
empty = DList{dl_counter = 1, dl_current = 0, dl_mem = IM.empty}

-- In a well-formed list, dl_current must point to a valid node
-- All operations below preserve well-formedness
well_formed :: DList a -> Bool
well_formed dl | IM.null (dl_mem dl) = dl_current dl == 0
well_formed dl = IM.member (dl_current dl) (dl_mem dl) 

is_empty :: DList a -> Bool
is_empty dl = IM.null (dl_mem dl)


-- auxiliary function
get_curr_node :: DList a -> Node a
get_curr_node DList{dl_current=curr,dl_mem=mem} = 
  maybe (error "not well-formed") id $ IM.lookup curr mem

-- The insert operation below makes a cyclic list
-- The other operations don't care
-- Insert to the right of the current element, if any
-- Return the DL where the inserted node is the current one
insert_right :: a -> DList a -> DList a
insert_right x dl | is_empty dl =
   let ref = dl_counter dl
   -- the following makes the list cyclic
   node = Node{node_val = x, node_left = ref, node_right = ref}
   in DList{dl_counter = succ ref,
dl_current = ref,
dl_mem = IM.insert ref node (dl_mem dl)}

insert_right x d...@dlist{dl_counter = ref, dl_current = curr, dl_mem = mem} =
  DList{dl_counter = succ ref, dl_current = ref, 
dl_mem = IM.insert ref new_node $ IM.insert curr curr_node' mem}
 where
 curr_node = get_curr_node dl
 curr_node'= curr_node{node_right = ref}
 new_node  = Node{node_val   = x, node_left = curr, 
  node_right = node_right curr_node}
 

get_curr :: DList a -> a
get_curr = node_val . get_curr_node

move_right :: DList a -> Maybe (DList a)
move_right dl = if next == 0 then Nothing else Just (dl{dl_current=next})
 where
 next = node_right $ get_curr_node dl

-- If no right, just stay inplace
move_right' :: DList a -> DList a
move_right' dl = maybe dl id $ move_right dl

fromList :: [a] -> DList a
fromList = foldl (flip insert_right) FL.empty

takeDL :: Int -> DList a -> [a]
takeDL 0 _ = []
takeDL n dl | is_empty dl = []
takeDL n dl = get_curr dl : (maybe [] (takeDL (pred n)) $ move_right dl)

-- Update the current node
update :: a -> DList a -> DList a
update x dl@(DList{dl_current = curr, dl_mem = mem}) = 
   dl{dl_mem = IM.insert curr (curr_node{node_val = x}) mem}
  where
  curr_node = get_curr_node dl


testl = fromList [1..5]
testl_s = takeDL 11 testl
testl1 = update (-1) testl
testl1_s = takeDL 11 testl1
testl2 = update (-2) . move_right' . move_right' $ testl1
testl2_s = takeDL 11 testl2
-- Old testl is still available
testl3 = update (-2) . move_right' . move_right' $ testl
testl3_s = takeDL 11 testl3

___
Haskell-Cafe mailing l

[Haskell-cafe] databases in Haskell & type-safety

2009-01-03 Thread Gour
Hi!

I'd like to use sqlite3 as application storage in my haskell project...

Browsing the available database options in Haskell it seems that:

a) HSQL is dead (hackage reports build-failure with 6.8 & 6.10)

b) haskelldb is also not in a good shape - build fails with 6.8 & 6.10

For Haskell-newbie as myself, it looks that haskelldb is the one which
provide(ed)s the most secure API (I was reading draft paper about
MetaHDBC but, apparently, the type inference support in open-source
databases is poor and that's why, according to the author "This is
unfortunately as it makes MetaHDBC a lot less valuable." 

What remains is:

c) Takusen which is also not up-to-date (it fails with 6.10) and

d) HDBC and sqlite bindings which are the only packages which build with
6.10.


However options in d) do not offer, afaik, type-safety which is emblem of
Haskell language, so I wonder how much this could be the problem for
real-world usage?

So, considering that HDBC nicely abstracts API enabling one to easily
switch from e.g. Sqlite3 to Postgres, and it is used as in example for
database programming, it seems as logical (and the only) choice for
Haskell database programming in a real-world?

I'm not familiar with Takusen which says: "Takusen's unique selling
point is safety and efficiency..." and I would appreciate if someone
could shed some more light to its 'safety' and the present status?


Sincerely,
Gour

-- 

Gour  | Zagreb, Croatia  | GPG key: C6E7162D



pgpECYShrDstY.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe