[Haskell-cafe] \Statically checked binomail heaps?

2009-10-18 Thread Maciej Kotowicz
Hi, first of all this post is literate haskell

I'm trying to implement a binomial heaps from okaski's book [1]
but as most it's possible to be statically checked for correctness of
definition.
Remark that binomial heap is list of binomial trees in increasing order of rank
and binomial heap of rank r is a node with r child t_1..t_r, where each t_i
is binomial tree of rank r - i


First I need some langue extension

 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE ScopedTypeVariables #-}

 module BinTree where


second type-level Nats and Bools, and Void i some kind of Top for Nats

 data Z
 data S a
 data Void
 data True
 data False

Ok, let define some nice types ;)
OrdLList is list of decreasing collections parametrised by type of
element and length
with is also highest rank of elements plus one, they are heterogeneous
by they ranks

 type Forest = OrdLList BinTree
 data OrdLList (t :: * - * - * ) a :: * - * where
   LNil :: OrdLList t a Z
   LCons :: t a n - OrdLList t a n - OrdLList t a (S n )

Binomial tree is here, a I know i can't check statically an heap property

 data BinTree a :: * - * where
   Node :: Ord a = a - Forest a n - BinTree a n

Heap is very similar to Forest just reversed order

 data  OrdGList  (t :: * - * - * ) a  :: * - * where
   GNil :: OrdGList t a Void
   GCons :: Lt n m  ~ True = t a n - OrdGList t a m - OrdGList t a n
 type Heap a n = OrdGList BinTree a n

Predicate for testing order in Heap

 type family Lt a b
 type instance Lt Z (S a) = True
 type instance Lt (S a) Z = False
 type instance Lt (S a) (S b) = Lt a b
 type instance Lt a Void = True

reflection form type-level nats to Int

 class TNum a where
   toNum :: a - Int
 instance TNum Z where
    toNum _ = 0
 instance TNum a = TNum (S a) where
    toNum _ = 1 + toNum (undefined :: a)

rank of binomial tree

 rank :: TNum n = BinTree a n - Int
 rank  t = toNum $  undefined `asTypeOf` (getN t)
 getN :: t a n - n
 getN _ = undefined :: n

root of binomial trees

 root :: BinTree e n - e
 root (Node x _ ) = x

And finally first of quite serious function
linking two trees with must have the same ranks, giving trees with
rank greater by one

 link :: Ord a = BinTree a n - BinTree a n - BinTree a (S n)
 link t1@(Node x c1) t2@(Node y c2)
   | x = y = Node x  $ LCons t2 c1
   | otherwise = Node y  $ LCons t1 c2

some simple trees for tests

 h =  GCons t3 $ GCons t GNil
 t = link t1 t2
 t1 = Node 3 LNil
 t2 = Node 2 LNil
 t3 = Node 5 LNil


And sadly that's all I can write...
for full functionality these data structure should have
merge, insert, deleteMin, findMin, defined in [1] as fallow

insTree t [] = [t]
insTree t ts@(t':ts')
 | rank t  rank t' = t : ts
 | otherwise = insTree (link t t') ts'

insert x = insTree (Node 0 x []) -- in [1] rank's are write explicit in nodes

merge ts [] = ts
merge [] ts = ts
merge ts1@(t1:ts1') ts2@(t2:ts2')
 | rank t1  rank t2 = t1 : merge ts1' ts2
 | rank t1  rank t2 = t2 : merge ts1 ts2'
 | otherwise = insTree (link t1 t2) $ merge ts1' ts2'

removeMinTree [] = error empty
removeMinTree [t] = (t,[]
removeMinTree (t:ts)
 | root t  root t' = (t,ts)
 | otherwise = (t',t:ts')
 where (t',ts') = removeMinTree ts

findMin = root . fst . removeMinTree
deleteMin ts = merge (rev ts1, ts2)
 where (Node _ x ts1,ts2) = removeMinTree

I try with all this function and with all I have problems with types
the types of insTree in my opinion should be sth like:

insTree :: (Min n m ~ k,TNum n, TNum m) = BinTree a n - Heap a m - Heap a k

where Min looks like:
type family Min a b
type instance Min a Z = Z
type instance Min Z a = Z
type instance Min (S a) (S b) = S (Min a b)


but this won't compile, ghc don't see that k can be the same type as m
in first pattern, problems with rest of function was similar
exclude removeMinTree with I have no idea what type it should have...

Have anyone an idea how make this code working?
Any help will be appreciated

[1] Purely Functional Data Structures by Chris Okasaki. Cambridge
University Press, 1998.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Happstack + network package issue on the Mac

2009-10-18 Thread Sean Leather
On Sat, Oct 10, 2009 at 15:13, Duncan Coutts wrote:

 From what Gregory and Anton have said, it sounds like the SockAddr6,
 HostAddress6 constructors should always be available, but that using
 them with the socket functions should fail at runtime on platforms with
 no IPv6 support, or when IPv6 support is turned off for some reason.

 That would probably make it rather easier to have portable programs that
 can optionally use IPv6. Having to use TH to test at compile time if a
 constructor is or is not exported from another package is more than a
 little unpleasant.


+1

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


Re: [Haskell-cafe] Lecture Notes Advanced Functional programming available

2009-10-18 Thread Sean Leather
 I am happy to announce that the rworked lecture notes for the 6th Advance
 Functional programming summer school have become available.


Thanks, Doaitse.


• Johan Jeuring (Utrecht University, NL): Libraries for Generic
 Programming in Haskell


An extended version of this article is available as a technical report:

  http://www.cs.uu.nl/research/techreps/UU-CS-2008-025.html

It introduces the concepts of datatype-generic programming using the
libraries LIGD, SYB, and EMGM and compares them. There's also an additional
section not in the published lecture notes on type-indexed datatypes with
type families. You can even do the exercises in the lecture notes and check
out the solutions in the tech report.

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


Re: [Haskell-cafe] Too much strictness in binary-0.5.0.2

2009-10-18 Thread Duncan Coutts
On Sat, 2009-09-19 at 00:36 +0400, Khudyakov Alexey wrote:
 Hello
 
 I run into problems with new binary package. Following function reads a list 
 of elements one by one until end of stream. List is very long (won't fit into 
 memory).

Sorry for the late reply.

 In binary-0.5.0.1 and earlier it read list lazily. Now it seems that it tries 
 to read whole list to memory. Program does not produce any output and memory 
 usage steadily grows.

Yes. We decided that having the Get monad as a lazy state monad just
doesn't make sense. It makes this one use case work, but causes more
problems generally. Certainly we need to be able to do lazy binary
deserialisation too, but our feeling is that it should be more explicit
and integrate better with error handling. Using a lazy state monad gives
us neither.

  getStream :: Get a - Get [a]
  getStream getter = do
empty - isEmpty
if empty
  then return []
  else do x - getter
  xs - getStream getter
  return (x:xs)
 
 How could I add laziness to this function to revert to old behavior.

You can make it explicitly lazy using something like:

getStream :: Get a - BS.ByteString - [a]
getStream getter bs = unfoldr step (bs, 0)
  where
step (bs, off) = case runGetState getOne bs off of
  (Nothing, _,   _   ) - Nothing
  (Just x,  bs', off') - Just (x, (bs', off'))

getOne = do
  empty - isEmpty
  if empty
then return Nothing
else fmap Just getter

Note the distinct lack of error handling, but if we had runGetState
return an Either then you could still make this code lazy, but you'd
have to decide what to do when you got a decoding error. You could at
this point translate it into a pure error, or enrich your output stream
type to account for the possibility of errors.

Note also that if we changed runGetState to do any error handling that
this would also break the lazy state monad properties that you were
previously relying upon.

Duncan

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


Re: [Haskell-cafe] Documentation (was: ANN: text 0.5, a major revision of the Unicode text library)

2009-10-18 Thread Sean Leather
Hi John,

On Sun, Oct 11, 2009 at 14:58, John Lato wrote:

 For anyone writing introductions to generic programming, take this as
 a plea from Haskellers everywhere.  If one of the RWH authors can't
 understand how to make use of these techniques, what hope do the rest
 of us have?


I would like to help you with this problem, though with a different library.
You can find EMGM [1] on Hackage. If you have a problem with the
documentation there, please let me know. I would consider it a bug. To
understand it, however, you should consider reading the tech report
Libraries for Generic Programming in Haskell [2], an extended version of
an article in a recently published collection of lecture notes from the 2008
Advanced Functional Programming Summer School [3].

  [1] http://hackage.haskell.org/package/emgm
  [2] http://www.cs.uu.nl/research/techreps/UU-CS-2008-025.html
  [3] http://www.springerlink.com/content/978-3-642-04651-3

I agree that a lot more documentation could help, but I hope this helps.

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


Re: [Haskell-cafe] Too much strictness in binary-0.5.0.2

2009-10-18 Thread Alexey Khudyakov
 Yes. We decided that having the Get monad as a lazy state monad just
 doesn't make sense. It makes this one use case work, but causes more
 problems generally. Certainly we need to be able to do lazy binary
 deserialisation too, but our feeling is that it should be more explicit
 and integrate better with error handling. Using a lazy state monad gives
 us neither.

This is valid point. I think I'll just use variant with explicit laziness.


 Note also that if we changed runGetState to do any error handling that
 this would also break the lazy state monad properties that you were
 previously relying upon.

I'd appreciate addition of error handling very much. Currently I have
to use ErrorT and do checks by hands. I have very simple parsers so
it's possible. It's not possible to do such things in general.

Trading laziness for error handling is good thing I believe. At the
moment it's hard to decode possibly malformed data.


On 10/17/09, Duncan Coutts duncan.cou...@googlemail.com wrote:
 On Sat, 2009-09-19 at 00:36 +0400, Khudyakov Alexey wrote:
 Hello

 I run into problems with new binary package. Following function reads a
 list
 of elements one by one until end of stream. List is very long (won't fit
 into
 memory).

 Sorry for the late reply.

 In binary-0.5.0.1 and earlier it read list lazily. Now it seems that it
 tries
 to read whole list to memory. Program does not produce any output and
 memory
 usage steadily grows.

 Yes. We decided that having the Get monad as a lazy state monad just
 doesn't make sense. It makes this one use case work, but causes more
 problems generally. Certainly we need to be able to do lazy binary
 deserialisation too, but our feeling is that it should be more explicit
 and integrate better with error handling. Using a lazy state monad gives
 us neither.

  getStream :: Get a - Get [a]
  getStream getter = do
empty - isEmpty
if empty
  then return []
  else do x - getter
  xs - getStream getter
  return (x:xs)

 How could I add laziness to this function to revert to old behavior.

 You can make it explicitly lazy using something like:

 getStream :: Get a - BS.ByteString - [a]
 getStream getter bs = unfoldr step (bs, 0)
   where
 step (bs, off) = case runGetState getOne bs off of
   (Nothing, _,   _   ) - Nothing
   (Just x,  bs', off') - Just (x, (bs', off'))

 getOne = do
   empty - isEmpty
   if empty
 then return Nothing
 else fmap Just getter

 Note the distinct lack of error handling, but if we had runGetState
 return an Either then you could still make this code lazy, but you'd
 have to decide what to do when you got a decoding error. You could at
 this point translate it into a pure error, or enrich your output stream
 type to account for the possibility of errors.

 Note also that if we changed runGetState to do any error handling that
 this would also break the lazy state monad properties that you were
 previously relying upon.

 Duncan


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


Re: [Haskell-cafe] x - String

2009-10-18 Thread Matt Morrow
On 10/17/09, Andrew Coppin andrewcop...@btinternet.com wrote:
 Derek Elkins wrote:
 See vacuum: http://hackage.haskell.org/package/vacuum

 Could be useful... Thanks!


As Derek mentioned, vacuum would be perfect for this:



-

import Data.Word
import GHC.Vacuum
import GHC.Vacuum.ClosureType
import qualified Data.IntMap as IM


type Info = (ClosureType  -- what kind of heap node is this?
,[String] -- [pkg,mod,con] for constructors
,[Int]-- pointers refering to other nodes in IntMap
,[Word])  -- literal data in constructors

overview :: HNode - Info
overview o =
  let ptrs = nodePtrs o
  lits = nodeLits o
  itab = nodeInfo o
  ctyp = itabType itab
  -- only available
  -- for constructors
  (pkg,mod,con) = itabName itab
  names = filter (not . null)
  [pkg,mod,con]
  in (ctyp
 ,names -- [] for non-data
 ,ptrs
 ,lits)

-- returns an adjacency-list graph
info :: a - [(Int,Info)]
info = fmap (\(a,b)-(a,overview b))
. IM.toList . vacuum

-- returns an adjacency-list graph
infoLazy :: a - [(Int,Info)]
infoLazy = fmap (\(a,b)-(a,overview b))
. IM.toList . vacuumLazy

-

-- example usage

data A a = A Int | B a | forall b. C b [A a]

val0 = [A 42, B (Left Nothing), C (pi,()) val0]
val1 = fmap (\n - C n []) [0..]

{-
ghci mapM_ print (info val0)
Loading package vacuum-1.0.0 ... linking ... done.
(0,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[1,2],[]))
(1,(CONSTR,[main,Main,A],[3],[]))
(2,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[4,5],[]))
(3,(CONSTR_0_1,[ghc-prim,GHC.Types,I#],[],[42]))
(4,(CONSTR,[main,Main,B],[6],[]))
(5,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[8,9],[]))
(6,(CONSTR_1_0,[base,Data.Either,Left],[7],[]))
(7,(CONSTR_NOCAF_STATIC,[base,Data.Maybe,Nothing],[],[]))
(8,(CONSTR,[main,Main,C],[10,0],[]))
(9,(CONSTR_NOCAF_STATIC,[ghc-prim,GHC.Types,[]],[],[]))
(10,(CONSTR_2_0,[ghc-prim,GHC.Tuple,(,)],[11,12],[]))
(11,(CONSTR_NOCAF_STATIC,[ghc-prim,GHC.Types,D#],[],[4614256656552045848]))
(12,(CONSTR_NOCAF_STATIC,[ghc-prim,GHC.Unit,()],[],[]))

ghci mapM_ print (infoLazy val1)
(0,(AP,[],[],[]))

ghci val1 `seq` ()
()

ghci mapM_ print (infoLazy val1)
(0,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[1,2],[]))
(1,(THUNK_2_0,[],[],[]))
(2,(THUNK_2_0,[],[],[]))

ghci length . take 2 $ val1
2

ghci mapM_ print (infoLazy val1)
(0,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[1,2],[]))
(1,(THUNK_2_0,[],[],[]))
(2,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[3,4],[]))
(3,(THUNK_2_0,[],[],[]))
(4,(THUNK_2_0,[],[],[]))

ghci case val1 of a:b:_ - a `seq` b `seq` ()
()

ghci mapM_ print (infoLazy val1)
(0,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[1,2],[]))
(1,(CONSTR,[main,Main,C],[3,4],[]))
(2,(CONSTR_2_0,[ghc-prim,GHC.Types,:],[5,6],[]))
(3,(CONSTR_0_1,[integer,GHC.Integer.Internals,S#],[],[0]))
(4,(CONSTR_NOCAF_STATIC,[ghc-prim,GHC.Types,[]],[],[]))
(5,(CONSTR,[main,Main,C],[7,4],[]))
(6,(THUNK_2_0,[],[],[]))
(7,(CONSTR_0_1,[integer,GHC.Integer.Internals,S#],[],[1]))
-}

-

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


[Haskell-cafe] Re: Merging modules (again)

2009-10-18 Thread pat browne
Hi,
I have tried qualified imports, synonyms and newtypes but still I could
not implement the merging task (previously posted). This is probably
because I have little knowledge of Haskell *or* the task is not really
suited to Haskell (more of a specification task than a programming task).

My main questions are;
 Can the merging task be achieved using the Haskell module system?

I also posted a question on how this task could be done using type
classes. I would ask the same question with respect to type classes.

Regards,
Pat



pat browne wrote:
 Hi,
 I want to establish the strengths and weakness of the Haskell module
 system for the ontology merging task (I know it was not designed for
 this!). I wish to make a new module (MERGEDONTOLOGY) from three input
 modules one of which is common to the other two.
 The desired merge should contain the following data types:
  Woman FinancialBank HumanBeing RiverBank
 Which are all identifiable without any qualifying module names.
 
 Below is the detailed requirement and my first attempt at this task in
 Haskell. I would be grateful for any information on how to merge these
 modules giving a set of unique unqualified types (i.e. without reference
 to their originating modules).
 
 Regards,
 Pat
 
 
 
 
 
 Informal Specification
 
 
 The diagram and text below explain the requirement
 
MERGEDONTOLOGY
   { Woman, RiverBank, FinancialBank, HumanBeing}
 /\  /\
/ \
   /\
  /  \
 / \
/   \
   / \
 
 ONTOLOGY1  ONTOLOGY2
 {Woman, Bank, Person}   {Woman, Bank, Human}
  /\  /\
   \  /
 \   /
  \ /
\ /
 \  /
  \   /
   \ /
 {Woman ,  Person}
COMMMON
 
 This example includes both synonyms and homonyms.
 1)The Woman sort (or data type) should be the same in all modules, there
 is only one Woman sort and it is named as such in each module. Hence
 there should be only one MERGEDONTOLOGY.Woman.
 
 2)There is only one sort MERGEDONTOLOGY.HumanBeing, but there are 3
 synonyms for it called ONTOLOGY2.Human, ONTOLOGY1.Person, and
 COMMON.Person. The last sentence considers ONTOLOGY1.Person and
 COMMON.Person as synonyms; they have different qualifiers but the
 intention is that they represnt the same thing. Hence should be mapped
 to same MERGEDONTOLOGY.HumanBeing. To do this (in Maude) COMMON.Person
 was  renamed to ONTOLOGY2.Human which in turn was renamed to
 MERGEDONTOLOGY.HumanBeing.
 
 3)The homonyms are ONTOLOGY1.Bank and ONTOLOGY2.Bank should become
 distinct sorts MERGEDONTOLOGY.RiverBank and
 MERGEDONTOLOGY.FinancialBank in the final ontology at the top of the
 diagram.
 
 
 
 My first attemt at merging using Haskell modules
 =
 module COMMON where
  data  Woman = WomanC
  data Person  = PersonC
 
 
 
 module  ONTOLOGY1 where
  import COMMON
  data Bank = BankC
 
 
 module ONTOLOGY2 where
  import COMMON
  data Bank = BankC
 
 
 
 module MERGEDONTOLOGY where
   import ONTOLOGY1
   import ONTOLOGY2
 
 If I use qualified names all the constructors are interpreted correctly
  MERGEDONTOLOGY :t COMMON.WomanC
  COMMON.WomanC :: COMMON.Woman
  MERGEDONTOLOGY :t COMMON.PersonC
  COMMON.PersonC :: COMMON.Person
  MERGEDONTOLOGY :t ONTOLOGY2.BankC
  ONTOLOGY2.BankC :: ONTOLOGY2.Bank
  MERGEDONTOLOGY :t ONTOLOGY1.BankC
  ONTOLOGY1.BankC :: ONTOLOGY1.Bank
  MERGEDONTOLOGY :t COMMON.Woman
 
 However, I wish that these types and constructors be fully defined in
 the context of the  MERGEDONTOLOGY. I have tried type synonyms and newtypes.
   type RiverBank = ONTOLOGY1.Bank
   type FinancialBank = ONTOLOGY2.Bank
   newtype RiverBank = BankC Int
 I have not explored import modes or qualified imports.
 
 
 


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


Re: [Haskell-cafe] Too much strictness in binary-0.5.0.2

2009-10-18 Thread Duncan Coutts
On Sun, 2009-10-18 at 19:53 +0400, Alexey Khudyakov wrote:
  Yes. We decided that having the Get monad as a lazy state monad just
  doesn't make sense. It makes this one use case work, but causes more
  problems generally. Certainly we need to be able to do lazy binary
  deserialisation too, but our feeling is that it should be more explicit
  and integrate better with error handling. Using a lazy state monad gives
  us neither.
 
 This is valid point. I think I'll just use variant with explicit laziness.
 
 
  Note also that if we changed runGetState to do any error handling that
  this would also break the lazy state monad properties that you were
  previously relying upon.
 
 I'd appreciate addition of error handling very much. Currently I have
 to use ErrorT and do checks by hands. I have very simple parsers so
 it's possible. It's not possible to do such things in general.
 
 Trading laziness for error handling is good thing I believe. At the
 moment it's hard to decode possibly malformed data.

It's possible to have both error handling and lazyness by extending the
result to include the representation of the errors.

Duncan

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


Re: [Haskell-cafe] Lecture Notes Advanced Functional programming available

2009-10-18 Thread Warren Henning
$83 and 3-4 weeks for a 300 page book? Oy vey.

Warren

On Fri, Oct 16, 2009 at 7:24 AM, S. Doaitse Swierstra
doai...@swierstra.net wrote:
 I am happy to announce that the rworked lecture notes for the 6th Advance
 Functional programming summer school have become available.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Error handling package

2009-10-18 Thread Michael Snoyman
While working on the next release of data-object, I wanted to represent some
operations that might fail. The typical candidates were:

1) Maybe
2) Either
3) Monad

Monad is always iffy because of the often times poorly defined fail. Maybe
doesn't provide any means of reporting what the problem was. Either is not
defined as a Monad in the base library. Also, the usual candidate of Either
String only provides for an error message. It would be nice to have more
in-depth information available.

So I've put together a package I call attempt. It defines a data type
called (surprise) Attempt with a Success and Failure constructor. The trick
here is that it using the new extensible exceptions under the surface, so
you can report any kind of exception you want. It also provides a
FromAttempt type class for possible conversion targets from an Attempt,
provides an attempt function with some helpers for performing the equivalent
of Control.Exception.catches, and provides two samples of functions I would
want to implement with this library: attemptJoin and attemptLookup.

My questions for the list are:

1) Is the overall approach sound, or do people have better ideas?
2) Are there any other FromAttempt instances I should provide out of the
box?
3) I was considering adding specialized versions of the fromAttempt
function, ie ioFromAttempt, maybeFromAttempt. Thoughts?
4) Should I follow the naming scheme attemptJoin, attemptLookup, etc, or
just call the functions join, lookup and force people to import the module
qualified?
5) Any other suggestions for attempt functions? I've considered
head/tail/etc.
6) Include ToAttempt?

The code is available on github at
http://github.com/snoyberg/attempt/blob/master/Data/Attempt.hs . I
appreciate the review. Also, I have not yet documented the code, but I will
do so before uploading to Hackage; I just didn't want to document a changing
target.

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


Re: [Haskell-cafe] Error handling package

2009-10-18 Thread Henning Thielemann


On Sun, 18 Oct 2009, Michael Snoyman wrote:


While working on the next release of data-object, I wanted to represent some 
operations
that might fail. The typical candidates were:

1) Maybe
2) Either
3) Monad

Monad is always iffy because of the often times poorly defined fail. Maybe 
doesn't
provide any means of reporting what the problem was. Either is not defined as a 
Monad in
the base library. Also, the usual candidate of Either String only provides for 
an error
message. It would be nice to have more in-depth information available.

So I've put together a package I call attempt. It defines a data type called
(surprise) Attempt with a Success and Failure constructor.


Does the explicit-exception package provide what you need?

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


[Haskell-cafe] Re: [Haskell-beginners] map question

2009-10-18 Thread Will Ness
Gregory Propf gregorypropf at yahoo.com writes:

 
 
 I actually meant it as sort of a joke but maybe it's not after all.  

Seriously though, using anything non-ASCII in source code is a bad idea, 
because there are lots of fonts and editors in the world.

It seems natural to me to have (`-`2) stand for (flip (-) 2), if only that 
would be made legal syntax, just as (`foldl`0) stands for (flip (foldl) 0).

Supposedly there is no reason to write (`:`[]) since : is already an infix 
operator, but making it a no-op wouldn't hurt, and would give us a benefit of 
being able finally to write the binary-minus flip-section in a visually 
apparent way.



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


Re: [Haskell-cafe] Re: [Haskell-beginners] map question

2009-10-18 Thread Luke Palmer
On Sun, Oct 18, 2009 at 4:47 PM, Will Ness will_...@yahoo.com wrote:
 Gregory Propf gregorypropf at yahoo.com writes:



 I actually meant it as sort of a joke but maybe it's not after all.

 Seriously though, using anything non-ASCII in source code is a bad idea,
 because there are lots of fonts and editors in the world.

 It seems natural to me to have (`-`2) stand for (flip (-) 2), if only that
 would be made legal syntax, just as (`foldl`0) stands for (flip (foldl) 0).

Or you could use the subtract function.

   map (subtract 2) [3,4,5]
  [1,2,3]

I don't think syntax sugar is worth it in this case.

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


Re: [Haskell-cafe] Error handling package

2009-10-18 Thread Michael Snoyman
(Sorry, accidently took off cafe.)

On Mon, Oct 19, 2009 at 12:44 AM, Henning Thielemann 
lemm...@henning-thielemann.de wrote:


 On Mon, 19 Oct 2009, Michael Snoyman wrote:

  Does the explicit-exception package provide what you need?

 http://hackage.haskell.org/package/explicit-exception


 I don't think so, but correct me if I'm wrong. I want to make it easy to
 chain together
 computations which could fail in different ways. For example, something
 like this:

 attemptReadInt :: String - Attempt Int
 attemptLookup :: String - [(String, String)] - Attempt String
 attemptLookupInt :: String - [(String, String)] - Attempt Int
 attemptLookupInt k m = attemptLookup k m = attemptReadInt

 Now, in the explicit-exception package, I could- in this simple example-
 define
 something like:

 data MyErrors = KeyNotFound | InvalidInt



 type Attempt = Exceptional MyErrors

True; that's what I meant by I could do this in my simple example.



  But this solution would not scale.


 You want to add other exceptions? The idea of my package is to make
 exceptions explicit in the type. Otherwise you would use
 extensible-exceptions. Or you could define MyErrors using an existential
 type.


Which is my point. I'm trying to provide a package for non-explicit
exceptions. To compare to other programming languages, I think your package
is providing the equivalent of Java checked exceptions, while mine is
providing (safe) unchecked exceptions. I say safe because you still need to
explicitly decide to turn an Attempt into a possible runtime exception which
will bring down your program.

Defining MyErrors using an existential type would essentially recreate the
entire attempt package; I don't see that purpose in everyone wanted
unchecked exceptions needing to reinvent the wheel in non-compatible ways.
If multiple libraries use attempt, they can easily have their
possible-error-returning functions chain together safely.




  Additionally, there's two immediate features I think I would miss from my
 package:

 1) fail works properly, so an Attempt would be a valid monad response from
 people who
 use that function.


 As far as I understand, 'fail' is used/abused for reporting failed pattern
 matches in do notation. If a failed pattern match indicates a programming
 error, it should be a really error, and not something that must be handled
 at run-time.


That's a lot of very debateable statements you just made. It might be that
it's strongly encouraged to only use fail for failed pattern matching, but
in practice you could use it for any monadic failure. Also, there's nothing
stopping a user from re-throwing pattern match exceptions received in an
Attempt.

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


[Haskell-cafe] Re: [Haskell-beginners] map question

2009-10-18 Thread Will Ness
Luke Palmer lrpalmer at gmail.com writes:

 
 Or you could use the subtract function.
 
map (subtract 2) [3,4,5]
   [1,2,3]

I don't want to.

 
 I don't think syntax sugar is worth it in this case.


I do. Operators are great because they make our intent visible, immediately 
apparent. Long words' meaning, like subtract's, is not immediately apparent, 
and they break consistency. Not everyone's first language in life was English, 
you see.

(`foldl`2) works.

(`-`2) should too.

I'll settle for (+(-2)) for now, but it ain't that pretty.


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


[Haskell-cafe] Problems with Haskell

2009-10-18 Thread Philippos Apolinarius
Before anything else, I want to point out that I have no intention to confront 
your community, or denigrate Haskell. A few days ago I answered an email from a 
Clean programmer on something related to Clean. He was worried that Clean team 
could give up its good work, and Clean could disappear; therefore, he was 
thinking about switching to Haskell. Since I thought that my email could be of 
interest for the Clean community, I posted it in the -- small-- Clean list 
:-(Clean is not as popular as Haskell). I received a lot of furious and 
offensive private emails for suggesting the Clean programmer to stick with 
Clean. However, I also received a very polite, humorous, and illuminating 
private email from a person who seems to work at Microsoft. His name is Simon 
Peyton-Jones. He
urged me to post my comments on a Haskell cafe. He also filed one of my 
comments as a bug in a Haskell bug track. Here is a couple of snippets from his 
email:

--- I think it's v bad that a straightforward program runs so slowly, and it's 
certainly true
that this is an area we could pay more attention to.

--- Meanwhile, I'm curious: are the arrays in Philippos's program strict?  Or 
lazy?  If strict,
that's a pretty big difference.

Therefore, here are my comments, with a lot of code. 

A few months ago I came accross an unpublished article about a novel genetic 
programming system. The system was coded in Larceny Scheme. I translated it to 
Clean and to Haskell. Unhappily, I cannot post the program here because it is 
very large, and the authors of the original Lisp program don't want me to 
divulge it before they see in in a printed page of a Journal. Therefore, I 
wrote an empty genetic programming framework, just to compare languages. 
Comparing Clean and Haskell, I noticed:

1 -- Clean compiler almost never let me do very stupid things, like trying to 
unbox a tree, or to write in a closed file (I will post an example of this in a 
near future). For instance, Clean compiler would never swallow something like 
the code below:


import Control.Monad.ST
import Data.Array.ST
import Data.Array.Base
import System.Random

data Op = AND | OR | NOT;
data Tree= L Double | T Op [Tree]

main = print $ runST
  (do arr - newArray (1,200) (L 0.0) :: ST s  (STArray s Int 
Tree)   
  
  go  arr 200 0.0 )

go ::  STArray s Int Tree - Int - Double - ST s Double
go a i acc
  | i  1 = return acc
  | otherwise=do 
   b - unsafeRead a i {- readArray a i -}
   writeArray a i (setDouble ((getDouble b)+3.0))
   c -  readArray a i 
   go  a (i-1) (acc+ (getDouble c))

-- What I really need is a random index in Haskell.
     
getDouble (L r)= r
getDouble _ = 0.0

setDouble r= L r

2 -- Safety does not cost much in Clean. For instance, removing array boundary 
check does not seem to affect Clean. I believe that it does not affect Haskell 
either, but I have not verified this point.

3 -- Haskell seems to loop more often than Clean. For instance, Haskell may 
loop if I change function mutate to

mutate e (L i) xs = (e, xs)
mutate e t (y:ys) = ins t (rnLen t y, ys) where
  ins (T p (L i:xs)) (0, st)=(T p (e:xs), st)
  ins (T p (t:xs)) (n,(r1:rs)) | n  0=
    let (T p mt, s2)= ins (T p xs)(n-1, rs)
  in (T p (t:mt), s2)
  ins (T p (t:xs)) (n,(r1:rs))
    | rn 2 r1== 0= (T p (e:xs), rs)
    | rn 2 r1== 1= let (xpr, st)= mutate e t rs
 in (T p (xpr:xs), st)
     
This might be a bug in my implementation of show Tree. It would be great if you 
people could show me what I did wrong.

4 -- On the plus side, there are libraries in Haskell that seem to behave 
better than the Clean equivalent libraries. This could be explained by the fact 
that there are a lot of people coding Haskell libraries, while Clean team seems 
to be reluctant in accepting libraries from outsiders. For instance, lethevert 
made a very important improvement in ObjectIO (changing fonts in edit text 
field), but it was never incorporated into Clean (yes, I wrote a lot of emails 
to Clean  team about it). Last year, when I was learning Clean, I discovered 
that many of my professors and teachers are presbyopic. Therefore, it would be 
a good policy to use very large fonts for homework. I only succeeded in doing 
it thanks to lethevert. In the case of the program below, Haskell System.Random 
library seems to work much better than Clean MersenneTwister.

5 --- Any improvement in the program below will be welcome. The program is 
already very fast thanks to suggestions I received from the bug track people, 
and from Peyton-Jones. Function show seems to loop if I replace mutate in 
item 3 for mutate in the code below. 

{- ghc gp.hs -O2 --make -}
{- Execute:  gp.exe +RTS -sstderr -}
import Control.Monad.ST
import Data.Array.ST
import Data.Array.Base
import System.Random

data Op = AND | OR | NOT;
data Tree= L Int | T Op [Tree]
psz= 2

Re: [Haskell-cafe] Re: [Haskell-beginners] map question

2009-10-18 Thread wren ng thornton

Will Ness wrote:

Luke Palmer lrpalmer at gmail.com writes:

Or you could use the subtract function.

   map (subtract 2) [3,4,5]
  [1,2,3]


I don't want to.


I don't think syntax sugar is worth it in this case.


I do. Operators are great because they make our intent visible, immediately 
apparent. Long words' meaning, like subtract's, is not immediately apparent, 
and they break consistency. Not everyone's first language in life was English, 
you see.


I'm with Luke on this one. It's a shame that negation uses the same 
symbolic identifier as subtraction, but introducing this new sugar only 
serves to make things more complex than they already are. If anything, 
negation should be moved to using a different identifier to remove the 
current ambiguity (as is done in some other languages).




(`foldl`2) works.

(`-`2) should too.


The `` syntax is for converting lexical identifiers into infix 
operators. Symbolic identifiers are already infix, which is why `` 
doesn't work for them. If we introduced this then those striving for 
consistency would be right in requesting that this pattern be allowed 
for all symbolic operators. I for one am opposed to introducing 
superfluous syntax for duplicating the current ability to write things 
in the same ways.


Attack the underlying problem, don't introduce hacks to cover up broken 
hacks. This isn't C++.


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


[Haskell-cafe] How to use bracket properly ?

2009-10-18 Thread zaxis

winSSQ count noRed noBlue = do {
yesRed -  [1..33] \\ noRed;
yesBlue - [1..16] \\ noBlue;
bracket (openFile ssqNum.txt WriteMode) (hClose) (\hd1 - pickSSQ
count yesRed yesBlue hd1);
return ()
}
will report:
Couldn't match expected type `IO ()' against inferred type `[()]'
In a stmt of a 'do' expression:
bracket
  (openFile ssqNum.txt WriteMode)
  (hClose)
  (\ hd1 - pickSSQ count yesRed yesBlue hd1)

However, the following works fine:

winSSQ count noRed noBlue = do
let yesRed =  [1..33] \\ noRed
let yesBlue = [1..16] \\ noBlue
bracket (openFile ssqNum.txt WriteMode) (hClose) (\hd1 - pickSSQ
count yesRed yesBlue hd1)

Why ?
-- 
View this message in context: 
http://www.nabble.com/How-to-use-%22bracket%22-properly---tp25953522p25953522.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] How to use bracket properly ?

2009-10-18 Thread Daniel Peebles
They're in different Monads. The first one does x - [...], which
means that you're operating in the list Monad instance, and bracket
operates in the IO Monad. The second one uses let x = [...] which
doesn't have any effect on what Monad you're in, so the whole thing
can be in IO.

Note that when you do x - [1..3]; y - [4..6] you're going to get all
9 pairs of values from x and y, by the way.

Hope this helps,
Dan

On Mon, Oct 19, 2009 at 1:33 AM, zaxis z_a...@163.com wrote:

 winSSQ count noRed noBlue = do {
    yesRed -  [1..33] \\ noRed;
    yesBlue - [1..16] \\ noBlue;
    bracket (openFile ssqNum.txt WriteMode) (hClose) (\hd1 - pickSSQ
 count yesRed yesBlue hd1);
    return ()
 }
 will report:
 Couldn't match expected type `IO ()' against inferred type `[()]'
    In a stmt of a 'do' expression:
        bracket
          (openFile ssqNum.txt WriteMode)
          (hClose)
          (\ hd1 - pickSSQ count yesRed yesBlue hd1)

 However, the following works fine:

 winSSQ count noRed noBlue = do
    let yesRed =  [1..33] \\ noRed
    let yesBlue = [1..16] \\ noBlue
    bracket (openFile ssqNum.txt WriteMode) (hClose) (\hd1 - pickSSQ
 count yesRed yesBlue hd1)

 Why ?
 --
 View this message in context: 
 http://www.nabble.com/How-to-use-%22bracket%22-properly---tp25953522p25953522.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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

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