Guarantees about shape of Generic's Rep

2021-04-20 Thread Alexey Khudyakov

Hi!

I have a question about guarantees that GHC provides about shape of generic
representation of data type. To be more concrete if we have two
single-constructor data types with N fields will their binary trees 
built from

(:*:) be balanced in same way? Same for (:+:) binary tree.

I want to use generics to write conversions between data types with same 
shape:


> λ> data Foo = Foo Int Char deriving (Show,Generic)
> λ> to . coerce . from $ Foo 1 'c' :: (Int,Char)
> (1,'c')
> λ> to . coerce . from $ Foo 1 'c' :: (Sum Int,Char)
> (Sum {getSum = 1},'c')
> λ> to . coerce . from $ (Sum (1::Int), 'c') :: Foo
> Foo 1 'c'

Coercion between Reps for different types is only possible when they 
have same
shape. Quick experiments shows that they're same. I think that they 
should be

same but documentation is silent about this.


Thanks in advance,
Alexey
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] compare lengths of lists lazily

2011-12-19 Thread Alexey Khudyakov

On 19.12.2011 19:29, Henning Thielemann wrote:


Shortest and most obfuscating solution I found is:


import Data.Ord (comparing)
import Control.Applicative (($))

compareLength :: [a] - [a] - Ordering
compareLength = comparing (()$)


comparingLength = comparing void

It's two character shorter

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


Erratic failure to specialize function

2011-12-18 Thread Alexey Khudyakov

Hello!


I've found a puzzling performance problem with code which uses vector
library and relies heavily on GHC to perform inlining and
specialization. In some cases compiler refuses to specialize function
and just copies there generic version which is slow.

Here is smallest test case I've manages to make:


file 'test.hs'

 import Criterion.Main
 import qualified Data.Vector.Unboxed as U
 import Boundary

 sample :: U.Vector Double
 sample = U.replicate 1 0

 main = defaultMain
   [ bench eta $ nf variance sample
   , bench lambda $ nf (\x - variance x) sample
   ]

file 'Boundary.hs'

 {-# LANGUAGE FlexibleContexts #-}
 module Boundary where
 import qualified Data.Vector.Generic as G

 variance :: (G.Vector v Double)
  = v Double - Double
 variance vec = G.sum vec
 {-# INLINE variance #-}

Here is benchmarking results:

benchmarking eta- mean: 220.8042 us
benchmarking lambda - mean: 24.31309 us

If variance is moved to the test.hs file or eta reduced or written
as lambda: varance = \vec - G.sum vec difference goes away.
What causes such behavior?



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


Re: [Haskell-cafe] How to get a file path to the program invoked?

2011-12-01 Thread Alexey Khudyakov

On 01.12.2011 23:47, dokondr wrote:

To be precise, $0 always contains the path to the program called. You
are right, this path will change depending on location from which the
program was called. So $0 is OK for my case, while current directory  is
unrelated.

Actually it contains whatever was passed to exec. By convention this is 
program name but it could be anything


#include stdio.h
#include unistd.h

int main(int argc, char** argv)
{
if( argc != 1 ) {
printf(%i: %s\n, argc, argv[0] );
} else {
execl(./argv,Random junk,,0);
}
return 0;
}

$ gcc argv.c -o argv  ./argv
2: Random junk




Try this:

#!/bin/sh
echo Arg 0: $0
echo All Parameters:  [$@]

Again, any way to get the same functionality in GHC?


getArgs and getProgName should do the trick

http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-Environment.html

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


Re: [Haskell-cafe] Is there any way to parametrize a value update using record syntax?

2011-09-06 Thread Alexey Khudyakov

On 07.09.2011 00:56, Brandon Allbery wrote:

2011/9/6 Poprádi Árpád popradi_ar...@freemail.hu
mailto:popradi_ar...@freemail.hu

updateData1 :: X - MonadicEnv()
updateData1 d = do; env - get; put env {data1 = d}


  updateData1 d = modify (\r - r {data1 = d})

But there is, sadly, no eta-reduced version of record update to make the
\r - r ... boilerplate go away; recognition of the syntax requires an
expression before the braces.  (Consider the ambiguity of the
eta-reduced expression modify {data1 = d}.)  Also, and much more
annoyingly, data1 must be constant.


In principle ambiguity could be resolved with a slash:
  modyfy \{data = d}


But that's from land of hypothetical language extension and dog headed 
people.


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


Re: Superclass defaults

2011-08-21 Thread Alexey Khudyakov

On 15.08.2011 14:36, Simon Peyton-Jones wrote:

With help from Conor we have made some progress on this: we have a draft design:
http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances

If you care about the issue, maybe you can help resolve the above questions. In 
particular, to give
concrete evidence for (b), working out some case studies would be a Good Thing. 
The examples given in other proposals using the extension proposed here would 
be one starting point.

I don't completely understant how does it work. Does client need to 
enable language extension to get default instances?


Also proposal cannot fix Functor/Applicative/Monad problem without 
breaking client code. It requires explicit opt-out but client may define 
Applicative instance. And unless hiding is added it will result in 
compile error.


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


Re: [Haskell-cafe] strictness properties of monoidal folds

2011-08-03 Thread Alexey Khudyakov

On 02.08.2011 08:16, Sebastian Fischer wrote:

Data.Foldable also provides the monoidal fold function foldMap. It is
left unspecified whether the elements are accumulated leftwards,
rightwards or in some other way, which is possible because the combining
function is required to be associative. Does this additional freedom for
implementors go so far as to allow for strict accumulation? Is it safe
to implement foldMap (without prime) with a strict accumulator or are
there examples where lazy accumulation is useful like in the above foldr
example and distinguishable from strict accumulation without breaking
the monoid laws?

Left and right folds behave identically for finite structures but they 
are different for infinite ones. Here is an example:



island = map First $ Just Snark : repeat Nothing

foldr mappend mempty island = First {getFirst = Just Snark}
foldl mappend mempty island = ⊥


If mappend is lazy arguments then strict and lazy could be distingushed. 
And Last indeed offers an example:


 island = [ error Boojum, Last (Just Snark) ]

 foldl  mappend mempty island = Last {getLast = Just Snark}
 foldl' mappend mempty island = Last {getLast = *** Exception: Boojum


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


Re: [Haskell-cafe] pointer equality

2011-07-21 Thread Alexey Khudyakov
 Any examples for hangups of 'smartEq' are greatly appreciated, I couldn't
 produce any so far.

Following sequences will hang smartEq. They are both infinite and aperiodic.
 smartEq (fromList primes) (fromList primes)
 smartEq (fromList pidigits) (fromList pidigits)

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


Re: [Haskell-cafe] Patterns for processing large but finite streams

2011-07-01 Thread Alexey Khudyakov
On Fri, Jul 1, 2011 at 12:21 PM, Eugene Kirpichov ekirpic...@gmail.com wrote:
 I meant the average of the whole list - given a sumS and lengthS (S
 for Stream), write meanS as something like liftS2 (/) sumS lengthS.

 Or is that possible with lazy lists too?

Sure you can. Sum, length and mean could be calculated as left
fold. If you need to calculate more that one statistic at time you
can combine accumulators

 sum = foldl (+) 0
 length = foldl (\n _ - n+1) 0
 data Mean Double Int
 mean = foldl (\(Mean m n) x - Mean (m + (x - m) / fromIntegral (n+1)) (n+1)) 
 (Mean 0 0)

AFAIU iteratees basically use same technique.

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


Re: [Haskell-cafe] Patterns for processing large but finite streams

2011-07-01 Thread Alexey Khudyakov
On Fri, Jul 1, 2011 at 12:54 PM, Eugene Kirpichov ekirpic...@gmail.com wrote:
 Alexey, your definition of mean does not look like liftS2 (/) sum
 length - you have to manually fuse these computations.

Well it was fused for numerical stability

 I'm asking for a formalism that does this fusion automatically (and
 guaranteedly).

Joining accumulators is quite straightforward. So is joining of initial
state. Just creating a
 joinAcc :: (acc1 - x - acc1) - (acc2 - x - acc2) - (acc1,acc2) - x - 
 (acc1,acc2)
 joinAcc f1 f2 (s1,s2) x = (f1 s1 x, f2 s2 x)

Still you have to handle them separately.
 sum' = foldl (+) 0
 len  = foldl (\n _ - n+1) 0
 sumLen = foldl (joinAcc (+) (\n _ - n+1)) (0,0)

There is more regular approach but it only works with statistics.
(function which do not depend on order of elements in the sample)
For every statistics monoid for its evaluation could be constructed.
For example sum:
 newtype Sum a = Sum a
 instance Num a = Monoid (Sum a) where
   mempty = Sum 0
   mappend (Sum a) (Sum b) = Sum (a+b)

Composition of these monoids becomes trivial. Just use


I pursued this approach in monoid-statistics[1] package.
It's reasonably well documented

 [1] http://hackage.haskell.org/package/monoid-statistics

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


Re: [Haskell-cafe] Why aren't there anonymous sum types in Haskell?

2011-06-21 Thread Alexey Khudyakov

On 22.06.2011 00:32, pipoca wrote:

On Jun 21, 4:15 pm, Alexander Sollaalex.so...@gmail.com  wrote:

The problem is that a sum type must name the different types, or else it
can't give access to them.  How is a function supposed to know if a value

blah :: A :+: B

is an A or a B?  It seems possible that it could figure it out, but that
problem is undecidable in general.


Why can't you use pattern matching?  We'd probably want to change the
syntax a little, to tell Haskell that we want to use an anonymous sum.

Something like:

foo :: Bar :+: Baz -  Quux
fooBar bar  = ...
fooBaz baz  = ...

Would finding the type signature of foo be undecidable?


Types may be same.

oops :: Int :+: Int - Int
oops Int i = mmm which one?

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


Re: [Haskell-cafe] Generating simple histograms in png format?

2011-06-12 Thread Alexey Khudyakov

On 11.06.2011 02:02, Dmitri O.Kondratiev wrote:

I am looking for platform-independent library to generate simple
histograms in png format.
Does such thing exist?



You may give chart[1,2] a try if dependency on cairo is acceptable.
It can generate PNG among other options.

[1] http://hackage.haskell.org/package/Chart
[2] http://dockerz.net/twd/HaskellCharts

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


Re: [Haskell-cafe] Plug space leak with seq. How?

2011-06-10 Thread Alexey Khudyakov


forever a   = a  forever a

doesn't tie to itself without optimisations, so my guess is that it gets
expanded when you run/eval/execState it in ghci, building the thunk

a  a  a  a  ...

If you define

forever' a = let a' = a  a' in a'

the variant using forever' runs in constant space in ghci.
This, like the explicit recursion, builds a cyclic structure, hence avoids
the leak.


I see. It's difficult to reason about space complexity in presence of 
optimizer.


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


[Haskell-cafe] Plug space leak with seq. How?

2011-06-09 Thread Alexey Khudyakov

Hello café!

This mail is literate haskell

I have some difficulties with understanding how bang patterns and seq
works.

 {-# LANGUAGE BangPatterns #-}
 import Control.Monad
 import Control.Monad.Trans.State.Strict

 leak :: State Int ()
 leak = do
   a - get
   put (a+1)
   leak

This function have obvious space leak. It builds huge chain of thunks
so callling `runState leak 0' in ghci will eat all memory. Fix is 
trivial - add bang pattern. However I couldn't achieve same

effect with seq. How could it be done?

 noLeak :: State Int ()
 noLeak = do
   a - get
   let !a' = (a + 1)
   put a'
   noLeak


Thanks.

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


Re: [Haskell-cafe] Plug space leak with seq. How?

2011-06-09 Thread Alexey Khudyakov

On 09.06.2011 20:09, Yves Parès wrote:

Is it not:

  noLeak :: State Int ()
  noLeak = do
a - get
** *let a' = (a + 1)
a' `seq` put a'*
noLeak

??



Indeed. Now I understand. It didn't work for me earlier because of
different behavior of 'forever' in ghci and compiled code.

This function leaks in ghci and do not in compiled code without 
optimizations (with optimizations GHC is smart enough  to make 
everything strict).


 noLeak = forever $ do { a - get; let a' = a+1; a' `seq` put a' }

Function with explicit recursion do not leak in both cases.

 noLeak = do { a - get; let a' = a+1; a' `seq` put a'; noLeak }

What causes this difference?

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


Re: [Haskell-cafe] ANN: quickcheck-properties

2011-05-30 Thread Alexey Khudyakov

On 30.05.2011 12:26, Bas van Dijk wrote:

On 30 May 2011 00:14, Alexey Khudyakovalexey.sklad...@gmail.com  wrote:

It always puzzled me why there are no packages for for testing general
type classes laws. (Monoid laws, monad laws etc). It looks like ideal
case for quickcheck and smallcheck.


How about 'checkers' by Conal Elliott:
http://hackage.haskell.org/package/checkers

We really need better search on hackage than C-f in browser. I didn't 
find them. Thank you for pointers.




Nice work by the way!

Bas



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


Re: [Haskell-cafe] ANN: quickcheck-properties

2011-05-30 Thread Alexey Khudyakov

On 30.05.2011 14:45, Henning Thielemann wrote:

Alexey Khudyakov schrieb:

On 30.05.2011 12:26, Bas van Dijk wrote:


How about 'checkers' by Conal Elliott:
http://hackage.haskell.org/package/checkers


We really need better search on hackage than C-f in browser. I didn't
find them. Thank you for pointers.


google with site:hackage.haskell.org option might help

It's do not offer much help. It finds too many pages for module 
descriptions packages get lost here.


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


Re: TypeFamilies vs. FunctionalDependencies type-level recursion

2011-05-29 Thread Alexey Khudyakov

On 29.05.2011 22:59, David Mazieres wrote:
 But now you have overlapping type synonyms, which pose a safety threat
 where the more-specific instance is not in scope.  Therefore, Haskell
 likely cannot be extended to accept code such as the above.


No it could. Inconsistency arise from fact that it's not guaranted that all
instances are known. Such guaranties are possible with closed type 
families.  In

such families instances could be added only in the same module with family
declaration.

Here is simplistic example:

 data HTrue
 data HFalse

 closed type family Equal a b :: *
 closed type instance a a = HTrue
 closed type instance a b = HFalse

No more instances could be added. So type could be determined unambigously.

In type level programming type families often meant to be closed but 
there is no

explicit way to say that and it limit their expressiveness. Also closed type
families could help with lack of injectivity. It could be untracktable 
though.




 One possible extension that *would* enable type-level recursive
 programming is the ability to constrain by inequality of types.  I
 noticed GHC is on its way to accepting a ~ b as a constraint that
 types a and b are equal.  If there were a corresponding a /~ b, then
 one might be able to say something like:

instance HLookup k (HCons (k, v) l) where
  ...
instance (h /~ (k, v), HLookup k l) =  HLookup k (HCons h l) where
  ...

I can't see how it change things. AFAIR instances selected only by their 
heads,

contexts are not taken into account.

Besides type inequality could be easily implemented with closed type
families. See code above. Here is contrived example of usage:

 instance (Equal Thing Int ~ HFalse) = Whatever Thing



P.S. Also I have suspicion that version with fundeps will behave badly 
if more

instances are added in another module.

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


[Haskell-cafe] ANN: quickcheck-properties

2011-05-29 Thread Alexey Khudyakov

Hello

It always puzzled me why there are no packages for for testing general
type classes laws. (Monoid laws, monad laws etc). It looks like ideal
case for quickcheck and smallcheck.

I'm glad to present package quickcheck-properties[1]. It containt set
of generic properties for semiroups, monoids, groups and
unsatisfactory imlementatation of functor's properties. Despite its name
package do not depend on quickcheck and could be used with smallcheck as 
well.


  
Examples
  

Here are few examples:

 quickCheck $ eq $ prop_Monoid (T :: T [Int])
+++ OK, passed 100 tests.
 quickCheck $ eq $ prop_Monoid (T :: T (Maybe [Int]))
+++ OK, passed 100 tests.


prop_Monoid tests all monoid properties: associativity, left and right
identity. T is used to fix type of monoid to test. It could be done
with type signature for prop_Monoid but writing signature for three
parameter function is just too cumbersome.

eq compares expression in properties using == operator. Many (most?)
of properties have form
 expression = another expression

Easiest solution is to compare them with ==. But is's not
satisfactory. Data type may not have Eq instance. Eq instance may
provide structural equality but some form of equivalince is
needed. etc. It's left to library user to decide how to compare
values.

In this contrived example lists are compared by length.
 eqOn length $ prop_Monoid (T :: T [Int])

  
Problems
  

There are unsolved problems. So it's announcement with
question. Functor/Applicative/Monads laws involve arbitrary functions.
It would be natural to generate them using quickcheck but I don't know
how to generate random functions. Any suggestions?

[1] http://hackage.haskell.org/package/quickcheck-properties


--
  Aleksey Khudyakov

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


Re: [Haskell-cafe] Exception for NaN

2011-05-16 Thread Alexey Khudyakov

On 16.05.2011 22:51, Casey McCann wrote:

How so? Equality on floating point values other than NaN works just
fine and behaves as expected. It's just that they violate all sorts of
algebraic laws when arithmetic is involved so sequences of operations
that should be equivalent aren't, in ways that are highly dependent on
the values being operated on.

Well not nessesarily. FPU may store intermediate values with more bits 
than in memory representation. When value is moved to memory from 
registers it loses some accuracy. So when you compare doubles for 
equality you may get true or false depending on compiler optimizations.


For example following C program prints 0 if compiled without 
optimitizations and 1 with -O2. (gcc 4.6.1)


#include math.h
#include stdlib.h
#include stdio.h

int main(int argc, char** argv)
{
double y = 1;
double x = tan(y);
printf(%i\n, x == tan(y));
return 0;
}

At any rate comparing floating points values for equality is asking for 
trouble.


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


[Haskell-cafe] Reformatter for Show

2011-05-02 Thread Alexey Khudyakov

Hello everyone!

Haskell have nice automatically derivable Show type class. It's quite 
useful for debugging with one exception. String representation of even 
moderately large value is completely unreadable (example below).


My question is there any tool for reformatting result of show so it 
could be read by human beings?




Real life example of world salad produced by show

 Module (SrcLoc {srcFilename = rec.hs, srcLine = 1, srcColumn = 1})
 (ModuleName Main) [OptionsPragma (SrcLoc {srcFilename = rec.hs,
 srcLine = 1, srcColumn = 1}) (Just GHC) -F -pgmF ./preprocessor ]
 Nothing (Just [EVar (UnQual (Ident main))]) [] [DataDecl (SrcLoc
 {srcFilename = rec.hs, srcLine = 3, srcColumn = 1}) DataType []
 (Ident Foo) [] [QualConDecl (SrcLoc {srcFilename = rec.hs,
 srcLine = 3, srcColumn = 12}) [] [] (RecDecl (Ident Foo) [([Ident
 asd],UnBangedTy (TyCon (UnQual (Ident Int,([Ident
 fgh],UnBangedTy (TyCon (UnQual (Ident String])] [(UnQual
 ...

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


Re: [Haskell-cafe] Reformatter for Show

2011-05-02 Thread Alexey Khudyakov

On 03.05.2011 00:43, Antoine Latter wrote:

On Mon, May 2, 2011 at 3:01 PM, Alexey Khudyakov
alexey.sklad...@gmail.com  wrote:

Hello everyone!

Haskell have nice automatically derivable Show type class. It's quite useful
for debugging with one exception. String representation of even moderately
large value is completely unreadable (example below).

My question is there any tool for reformatting result of show so it could be
read by human beings?




You could use the 'groom' package on Hackage:

http://hackage.haskell.org/package/groom

It works best for the derived show instances.

Antoine



 http://hackage.haskell.org/package/pretty-show

 Just use ppShow, instead of show.

 Hope this helps,
 Ozgur

Thanks a lot. It's exactly what I looked for. Both packages do they jobs

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


Re: [Haskell-cafe] Binary and Serialize classes

2011-04-28 Thread Alexey Khudyakov
 Speaking of that Double instance... both data-binary and cereal use
 decodeFloat and encodeFloat which mean they suffer from the same
 problems as realToFrac, namely that -0 becomes 0 and NaN becomes
 -Infinity (I'm not sure why the latter happens since the decoded
 values differ... must be a problem with encodeFloat).  It's tempting
 to just get the ieee754 bitmap out and serialize that.  I know I've
 seen this question around before, but is it possible to somehow cast a
 D# directly to bytes?  I know I can write a C function and FFI that
 in, but it would be tidier to do it all in haskell.  I guess I can
 probably use castPtr and memCpy, but I don't see the required
 addressOf.  I.e. how would I write 'memcpy(buf, d, sizeof(double));'?

Also serialized data takes ~3 times more space than IEEE754
representation. It's a concern when a lot of data is serialized.
Serialization in IEEE754 format is implemented already for binary.
You can check package data-binary-ieee754[1] for

[1] http://hackage.haskell.org/package/data-binary-ieee754

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


Re: [Haskell-cafe] Synthetic values?

2011-02-09 Thread Alexey Khudyakov

On 09.02.2011 20:57, Chris Smith wrote:

On Wed, 2011-02-09 at 18:15 +0100, Cristiano Paris wrote:

I've a type problem that I cannot solve and, before I keep banging my
head against an unbreakable wall, I'd like to discuss it with the
list.


If I'm understanding your high-level goals correctly, then you're going
about things the wrong way.  It looks like in your Sealed type, you're
accumulating a list of type class constraints that are needed by a
phantom type, in order to access the value.  But type classes are open;
anyone can make any new type an instance of the type class whenever they
want.



It's possible to have closed type classes. Trick consist in adding 
unsatisfiable constraint. For example:


 -- This type class is not exported
 class Private a
 class Private a = PRead a

If Private is not exported one cannot add instances to PRead.

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


Re: [Haskell-cafe] Synthetic values?

2011-02-09 Thread Alexey Khudyakov

On 09.02.2011 20:15, Cristiano Paris wrote:

Now the problem.

I would like to enforce permissions not at the role level, but at the
permissions level. Let's say that I want to leave unseal unchanged,
I'd like to construct a p-value for unseal combining functions
checking for single permissions, that is, in pseudo-code:



So far I got only frustration. In principle it seems possible to
achieve this result because everything is known at compile time and
the type-checked should have all the information available to enforce
the security constraints.

Anyhow, I couldn't write any usable code.



Text below is literate haskell

My solution is based on heterogenous lists and require number of
language extensions. I'd recomend to read paper Strongly typed
heterogeneous collections[1] which describe this technique in detail

 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE FlexibleInstances #-}

So lets start with definition of type classes for permissions and data
types which represent such permissions.

 class PRead  a
 class PWrite a

 data WRead  = WRead
 data WWrite = WWrite

Now interestig part begins. We need to compose different permissons. I
define heterogenous list for that purpose. It's nothing more than a
nested tuple in disguise.

 data a ::: b = a ::: b
 infixr :::

List has instance for some permission if it has corresponding type in
it. Please note that I make use of overlapping here. You may need to
read about it.

Also list need some terminator. WRead is not instance of PRead whereas
WRead ::: () is. I will use () for that purpose. It's OK since all
type classes here are closed.

 instancePRead (WRead ::: b)
 instance PRead b = PRead (a ::: b)

 instance PWrite (WWrite ::: b)
 instance PWrite b = PWrite (a ::: b)

Here is function for checking that everything is working as expected

 withR :: PRead a = a - ()
 withR _ = ()

 withW :: PWrite a = a - ()
 withW _ = ()

 withWR :: (PRead a, PWrite a) = a - ()
 withWR _ = ()

 r  = WRead ::: ()
 w  = WWrite ::: ()
 rw = WRead  ::: WWrite ::: ()

[1] http://homepages.cwi.nl/~ralf/HList/



P.S. You can use phantom types to propagate type information. I feel
that carrying undefined is morally dubious practice.

 data T a = T
 newtype Sealed p a = Sealed a

 unseal :: T p - Sealed p a - a
 unseal _ (Sealed x) = x

 admin :: T (WRead  ::: WWrite ::: ())
 admin = T

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


Re: [Haskell-cafe] Synthetic values?

2011-02-09 Thread Alexey Khudyakov

On 09.02.2011 23:16, Cristiano Paris wrote:

On Wed, Feb 9, 2011 at 19:33, Alexey Khudyakov
alexey.sklad...@gmail.com  wrote:

...
If Private is not exported one cannot add instances to PRead.


Nice trick. I would have thought of hiding the classes PRead and
PWrite but I'm not sure if it could break the code.

It shouldn't but it would be impossible to write signatures for 
polymorphic functions which use thoose type classes.


foo :: PWrite p = Sealed p Int  -- impossible to write
foo = ...

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


Re: [Haskell-cafe] Byte Histogram

2011-02-06 Thread Alexey Khudyakov

On 06.02.2011 23:29, Johan Tibell wrote:

On Sun, Feb 6, 2011 at 8:48 PM, Andrew Coppin
andrewcop...@btinternet.com  wrote:

In particular, I get strange looks from people in the OOP community when I
say I'm using a language that doesn't have any abstractions at all for
dealing polymorphically with containers. In general, it's almost impossible
to write a Haskell function that will work with a list, an (immutable)
array, a hash table or a map, polymorphically.


I think one reason we haven't seen a type class for containers is that
it isn't easy to create one using vanilla type classes (see Simon PJ's
paper on the topic.)

Well Foldable and Traversable provide set of generic operations for 
containers. Although they are quite limited, containter must be 
polymorphic (e.g. no IntMap) and parameter must be of any type (e.g. no 
unboxed vectors) both are still quite useful.


Also there is a container-classes package which provide set of type 
class for containers.


[1] http://hackage.haskell.org/package/container-classes

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


Re: [Haskell-cafe] Byte Histogram

2011-02-06 Thread Alexey Khudyakov

On 07.02.2011 00:37, Johan Tibell wrote:

Also there is a container-classes package which provide set of type class
for containers.


I'd like to avoid MPTC and fundeps if possible.

I think haskell2010's type system is just not expressive enough to 
create interface generic enough. It's not possible to create type class 
which will work for both ByteStrings (or IntSet) and lists.



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


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread Alexey Khudyakov

On 04.01.2011 13:24, o...@okmij.org wrote:


I'd like to argue in opposition of making Functor a super-class of
Monad. I would argue that superclass constraints are not the right
tool for expressing mathematical relationship such that all monads are
functors and applicatives.

Then argument is practical. It seems that making Functor a superclass
of Monad makes defining new monad instances more of a chore, leading
to code duplication. To me, code duplication is a sign that an
abstraction is missing or misused.




I think I understood your point. But it looks like that it's possible to 
use subclass's function in superclass instance. At very least GHC is 
able to do it.


Following example works just fine without any language extensions in 
GHC6.12.3



import Prelude hiding (Monad(..), Functor(..))

class Functor f where
  fmap :: (a - b) - f a - f b

class Functor m = Monad m where
  return :: a - m a
  (=) :: m a - (a - m b) - m b

instance Functor Maybe where
  fmap f m = m = (return . f)
instance Monad Maybe where
  return = Just
  Nothing = _ = Nothing
  Just x  = f = f x

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


Re: Rigid types fun

2010-11-05 Thread Alexey Khudyakov

On 05.11.2010 14:08, Mitar wrote:

So I know I can move some hard-coded combination into a function. But
I would like to cover all combinations and tell with arguments which
combination I want.

I'm not sure what do you exactly want. But what about applicative 
functors? They offer nice notation


 Nerve $ (Axon $ newChan) * (AxonAny $ newChan)
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] Re: Rigid types fun

2010-11-05 Thread Alexey Khudyakov

On 05.11.2010 14:08, Mitar wrote:

So I know I can move some hard-coded combination into a function. But
I would like to cover all combinations and tell with arguments which
combination I want.

I'm not sure what do you exactly want. But what about applicative 
functors? They offer nice notation


 Nerve $ (Axon $ newChan) * (AxonAny $ newChan)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-11-05 Thread Alexey Khudyakov



We already know that there are noncommutative modules/vectorspaces of
interest (e.g., modules over quaternions and modules over graph paths),
why not support them from the beginning? It seems like you're going out
of your way to exclude things that would be trivial to include. This is
exactly why this is my standard complaint against the various proposals
out there for new numeric hierarchies. People who are used to only using
R^n think the proposals are just fine, but none of the proposals capture
the structures I work with daily. Which means the new proposals are no
better than the Prelude for me.

Could you tell what data structures do you use? It's difficult to think 
about them without concrete examples.

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


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-10-31 Thread Alexey Khudyakov
On Sat, Oct 30, 2010 at 2:07 PM, Henning Thielemann
schlepp...@henning-thielemann.de wrote:
 wren ng thornton schrieb:
 On 10/22/10 8:46 AM, Alexey Khudyakov wrote:
 Hello everyone!

 It's well known that Num  Co type classes are not adequate for vectors
 (I don't mean arrays). I have an idea how to address this problem.

 Conal Elliott wrote very nice set of type classes for vectors.
 (Definition below). I used them for some time and quite pleased. Code is
 concise and readable.

   class AdditiveGroup v where
   zeroV :: v
   (^+^) :: v - v - v
   negateV :: v - v
 [...]
 I'd like to know opinion of haskellers on this and specifically opinion
 of Conal Eliott as author and maintainer (I CC'ed him)

 Looks like you are about to re-implement numeric-prelude. :-)

Only limited subset. Very limited. Everything is too big to be implemented

 Vector (Complex a) is a vector with respect to both 'a' and 'Complex a'.

It is but it's difficult to encode this. Type class below allows to have
multiple scalars. But then type checker cannot infer type of 2 in expression
`2 *^ vector' and so type signature must be added which is hardly usable

class Module v s where
  (*^) :: s - v - v

I think one is forced to convert real number to complex or use some
operations specific to data type.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-10-31 Thread Alexey Khudyakov
On Wed, Oct 27, 2010 at 2:53 AM, wren ng thornton w...@freegeek.org wrote:
 On 10/26/10 8:51 AM, Alexey Khudyakov wrote:

 On 24.10.2010 03:38, wren ng thornton wrote:

 I don't care much about the name of the class, I'd just like support for
 monoids, semirings,... when they lack a group, ring,... structure.

 Then what about following type class hierarchy? I think it supports
 those structures. Only restriction is that it forces one to have both
 left and right modules. It's possible to split them but I think it will
 be to painful for vector spaces over R and C.

 class Module v where
 type Scalar v :: *
 (*^) :: Scalar v → v → v
 (^*) :: v → Scalar v → v
 (^*) = flip (*^)

 Is there any good reason for forcing them together? Why not, use the
 hierarchy I proposed earlier? If you want to reduce the clutter in type
 signatures for real and complex vector spaces then just add to my previous

    -- Or just call it Module if preferred.
    class (LeftModule v, RightModule v) = AssociativeModule v where
        -- Law: (^*) == flip (*^)

 This way, when (not if) people want nonassociative modules the classes are
 already there. The additional overhead in defining an associative module is
 only three lines when using default implementation; two lines otherwise:

    type instance Scalar Foo = Bar
    instance AssociativeModule Foo where
    instance RightModule Foo where
        (^*) = flip (^*)
    instance LeftModule Foo where
        (*^) = ...
 vs

    instance Module Foo where
        type Scalar Foo = Bar
        (*^) = ...

 And once it's defined, the usage is the same: just require AssociativeModule
 and you'll pull in both (*^) and (^*).

Main reason is that it complicate creation of instances for types for which
multiplication is associative and commutative more complicated.
Programmer must write three instances instead of one and they must
satisfy some law. It leads to code which more difficult to understand and
contain more bug (mostly dumb).

This is tradeoff between usability and generality. Modules are much less
frequent and much less known than vector space. I for example didn't known
about their existence before. I think difficulties should be pushed on
the people
who define instances for non associative modules.

One possibility is to add separate type classes for left and right modules
and require that is type is has both Module and LeftModule instances
(*^^) == (*^)

  class Module v where
(^*) :: v - Scalar v - v
(*^) :: Scalar v - v - v

Of course code that is written to work with left/right modules wont work with
associative modules.



 We already know that there are noncommutative modules/vectorspaces of
 interest (e.g., modules over quaternions and modules over graph paths), why
 not support them from the beginning? It seems like you're going out of your
 way to exclude things that would be trivial to include. This is exactly why
 this is my standard complaint against the various proposals out there for
 new numeric hierarchies. People who are used to only using R^n think the
 proposals are just fine, but none of the proposals capture the structures I
 work with daily. Which means the new proposals are no better than the
 Prelude for me.

I have to admit that I with R^n and therefore mostly care about this use
case. I think good set of type classes should be small enough (IMHO five or so).
It should not require to write unnecessary code in common cases. Probably this
is case when rule one size doesn't fit all applies.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-10-26 Thread Alexey Khudyakov

On 24.10.2010 03:38, wren ng thornton wrote:

On 10/23/10 4:53 PM, Alexey Khudyakov wrote:

On 23.10.2010 05:11, wren ng thornton wrote:

I'd rather see,

class Additive v where -- or AdditiveMonoid, if preferred
zeroV :: v
(^+^) :: v - v - v

class Additive v = AdditiveGroup v where
negateV :: v - v


Seems good for me. One more instance declaration to write and no changes
in usage.

However when written this way it becomes obvious that
`zeroV' == `mempty' and ^+^ = mappend. Is Additive really needed then?


It depends on the usage, since we don't have a nice way of having
multiple Monoid instances in scope with different identifiers for their
respective mzero/mappend. For example, in Edward Kmett's monoids[1]
library he reuses Monoid for additive monoids and adds a new
Multiplicative class for multiplicative monoids; that way you can use
operators for a semiring without needing newtype wrappers everywhere in
order to distinguish the two structures on the same type.

When dealing with modules and vector spaces we have three or four
different monoids in play: the additive and multiplicative monoids of
the underlying semiring/ring/field, and the additive and multiplicative
monoids of the module/vectorspace. Lacking the aforementioned feature,
that means there are good reasons to have duplicate classes (i.e.,
they're all monoids) so long as they are documented as capturing
different notions (e.g., distinguishing scalar and vectorial uses).

I don't care much about the name of the class, I'd just like support for
monoids, semirings,... when they lack a group, ring,... structure.

Then what about following type class hierarchy? I think it supports 
those structures. Only restriction is that it forces one to have both 
left and right modules. It's possible to split them but I think it will 
be to painful for vector spaces over R and C.



class AdditiveMonoid v where
  (^+^) :: v → v → v
  zeroV :: v

class AdditiveMonoid ⇒ AdditiveGroup v where
  negateV :: v → v
  -- For performance sake
  (^-^) :: v → v → v
  v ^-^ u = v ^+^ negateV u

class Module v where
  type Scalar v :: *
  (*^) :: Scalar v → v → v
  (^*) :: v → Scalar v → v
  (^*) = flip (*^)

class (AdditiveGroup v, Module v) ⇒ VectorSpace v

class VectorSpace v ⇒ InnerSpace v where
  (.) :: v → v → Scalar v

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


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-10-23 Thread Alexey Khudyakov

On 23.10.2010 05:11, wren ng thornton wrote:

On 10/22/10 8:46 AM, Alexey Khudyakov wrote:

Hello everyone!

It's well known that Num  Co type classes are not adequate for vectors
(I don't mean arrays). I have an idea how to address this problem.

Conal Elliott wrote very nice set of type classes for vectors.
(Definition below). I used them for some time and quite pleased. Code is
concise and readable.

 class AdditiveGroup v where
 zeroV :: v
 (^+^) :: v - v - v
 negateV :: v - v
[...]
I'd like to know opinion of haskellers on this and specifically opinion
of Conal Eliott as author and maintainer (I CC'ed him)


Just my standard complaint: lack of support for semirings, modules, and
other simple/general structures. How come everyone's in such a hurry to
run off towards Euclidean spaces et al.?

They give familiar warm fuzzy feeling. It's same as monads and 
applicative functors (-:



I'd rather see,

class Additive v where -- or AdditiveMonoid, if preferred
  zeroV :: v
  (^+^) :: v - v - v

class Additive v = AdditiveGroup v where
  negateV :: v - v

Seems good for me. One more instance declaration to write and no changes 
in usage.


However when written this way it becomes obvious that
`zeroV' == `mempty' and ^+^ = mappend. Is Additive really needed then?


type family Scalar :: * - *

class Additive v = LeftModule v where
  (*^) :: Scalar v - v - v

class Additive v = RightModule v where
  (^*) :: v - Scalar v - v


Could you give some example of data type for which (*^) ≠ flip (^*)?
I couldn't imagine one.


...

Though I don't know how much that'd affect the niceness properties you
mentioned.



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


Re: [Haskell-cafe] vector-space and standard API for vectors

2010-10-23 Thread Alexey Khudyakov

On 24.10.2010 01:19, Daniel Peebles wrote:

Just out of curiosity, why do you (and many others I've seen with
similar proposals) talk about additive monoids? are they somehow
fundamentally different from multiplicative monoids? Or is it just a
matter of notation? When I was playing with building an algebraic
hierarchy, I picked a neutral operator for my monoids (I actually
started at magma, but it's the same thing) and then introduced the
addition and multiplication distinction at semirings, as it seemed
pointless to distinguish them until you have a notion of a distributive
law between the two.

I'm not sure that I understood your question completely. But I think it 
happens naturally. Authors of such proposals just don't think about 
monoids and abstract algebra. They think about R^n. It appears quite 
frequently (well it depends on domain) and NumCo is useless. Proposals 
are born out of that frustration.


Probably people who do care about distinction between additive and 
multiplicative monoids don't face that problem or it's

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


[Haskell-cafe] vector-space and standard API for vectors

2010-10-22 Thread Alexey Khudyakov

Hello everyone!

It's well known that Num  Co type classes are not adequate for vectors 
(I don't mean arrays). I have an idea how to address this problem.


Conal Elliott wrote very nice set of type classes for vectors. 
(Definition below). I used them for some time and quite pleased. Code is 
concise and readable.


 class AdditiveGroup v where
   zeroV :: v
   (^+^) :: v - v - v
   negateV :: v - v

 class AdditiveGroup v = VectorSpace v where
   type Scalar v :: *
   (*^) :: Scalar v - v - v

 class VectorSpace v = InnerSpace v where
   (.) :: v - v - Scalar v

There are few problems though. Fisrt one is inlining. Functions are not 
inlined so if client code uses uses stream fusion it breaks. Second is 
dependecies. Vector-space doesn't have big chain of dependencies. People 
may be reluctant to use vector-spaces just for API for small packages.


My proposal is to split type classes above into separate package which 
provide only type classes, doesn't have any dependencies.
Second point is to lean more on performance side in performance vs 
elegance. Add INLINE pragmas everywhere (unfortunate feature of stream 
fusion), move ^-^ to AdditiveGroup with default implementation.


I'd like to know opinion of haskellers on this and specifically opinion 
of Conal Eliott as author and maintainer (I CC'ed him)

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


Re: [Haskell-cafe] How to catch exception within the Get monad (the Binary package)

2010-09-07 Thread Alexey Khudyakov

On 07.09.2010 20:51, Henning Thielemann wrote:

This solution looks very ugly to me. Catching 'error's is debugging, but
parser failure is kind of exception handling. I guess, the errors you
want to catch are caused by non-supported fail method, right? Can't you
use a monad transformer like explicit-exception:Synchronous.Exception or
transformers:ErrorT around the Binary parser?

ErrorT is useless here since it cannot intercept calls to 'error'. Same 
should be the case with ExcepcionalT. There is also performance penalty


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


Re: [Haskell-cafe] How to catch exception within the Get monad (theBinary package)

2010-09-05 Thread Alexey Khudyakov

On 05.09.2010 22:02, Don Stewart wrote:

For strict, checked binary parsing, use the cereal package. For lazy
binary parsing with async errors, use binary.

Unfortunately cereal is too slow. I got ~5x slowdown with cereal and had 
to patch binary in order to incorporated error handling (essentially 
same as in cereal but simpler).



They're the main two points in the design space. The other is to tag the
lazy stream, and insert failure tags in the structure.

It won't help againist not enough input errors. Sometimes fragments of 
data I process are damaged they are too short, some bits are flipped 
etc. There is no way to guard againist beforementioned errors but to 
constantly check that there is enough data in stream. Also error 
handling is very useful in signalling that data is malformed. It's 
possible to use cereal but it's too slow and it's inconvenient to have 
both Binary and Serialize instances.


Also beginnig from 0.5.0.2 Get monad is strict and consume all required 
input at once. And therefore isn't suitable for lazy parsing unless 
lazyness is introduced manually.

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


Re: [Haskell-cafe] Filename encoding error (was: Perform a research a la Unix 'find')

2010-08-22 Thread Alexey Khudyakov

On 22.08.2010 21:23, Yves Parès wrote:

In fact the encoding problem is more general.

When I simply do 'readFile bar/fooé', then I'm told:
*** Exception: bar/fooé: openFile: does not exist (No such file or
directory)

How am I supposed to read files whose names contains non-ASCII characters?
(I use GHC 6.12.3 under Ubuntu 10.04 32bits)

Unicode handling in GHC always was a problem. There are corresponding 
tickets in bug tracker [1,2]


You have to manually encode/decode strings to/from UTF8 which obviously 
works only for UTF8 locales.


[1] http://hackage.haskell.org/trac/ghc/ticket/3307
[2] http://hackage.haskell.org/trac/ghc/ticket/3309
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANNOUNCE: binary-generic-0.2, generic binary serialisation using binary and syb.

2010-08-20 Thread Alexey Khudyakov

On 21.08.2010 01:38, Lars Petersen wrote:

* Float and Double are serialised big-endian according to binary-ieee754


I'd like to point out that binary-ieee754 is dead slow[1] and not usable 
when one cares about performance. IMHO lack of ways to serialize 
floating point data in IEEE754 format is one of the problems of binary 
package.


[1] ~30 times slower that reading/writing with peek/poke although I had 
to patch binary for that.


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


Re: [Haskell-cafe] Why is toRational a method of Real?

2010-08-05 Thread Alexey Khudyakov

On 05.08.2010 13:35, Henning Thielemann wrote:


On Wed, 4 Aug 2010, John Meacham wrote:


The numeric classes are sort of messed up when it comes to non integral
values. (not that they are perfect for other things) for instance,
realToFrac doesn't preserve NaN or Infinity,


Why should realToFrac do this? NaN, Infinity and +/-0 are IEEE hacks for
the common numerical applications you do with floating point numbers.
These special values could be supported by floating point specific, or
even IEEE specific type classes, but they should not be part of
mathematically motivated type classes .

But they are. isNaN, isInfinite, isNegativeZero are all members of 
RealFloat type class and there is no generic for type conversion which 
conserves NaNs. Numeric type classes are really messed up.

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


Re: [Haskell-cafe] Playing with ATs again

2010-08-03 Thread Alexey Khudyakov

On 03.08.2010 21:25, Andrew Coppin wrote:

Now suppose that instead of a container type with an associated element
type, what we want is several pairs of types having a one-to-one
relationship, and we want to be able to traverse that relationship in
either direction. What's the best way to do that?

(I tried just having two mirror image classes like the one above. But
that doesn't work; there's no guarantee that going one way and then
going back the other way will definitely take you back to where you
started. I tried to make that a constraint, and got an error message
that basically says this feature is not implemented. Great. Still,
there's probably a better way to do this.)

That's possible with multiparameter type classes and fundeps. Without 
any further words I'm pasting code snippet:


 class Relator a b | a - b, b - a where
   to   :: a - b
   from :: b - a

 data Knight = Knight deriving Show
 data Dragon = Dragon deriving Show

 instance Relator Knight Dragon where
   to   _ = Dragon
   from _ = Knight

I'm not sure that it's what you want.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Announce type-level-natural-number-1.0: Simple, Haskell 2010-compatible type level natural numbers

2010-07-31 Thread Alexey Khudyakov
On Fri, 30 Jul 2010 15:20:55 -0700
John Meacham j...@repetae.net wrote:
   type family Add n m :: *
  
   type instance Add Zero  Zero   = Zero
   type instance Add Zero (SuccessorTo n) = SuccessorTo n
   type instance Add (SuccessorTo n) m= SuccessorTo (Add n m)
  
  Standard package is could be somewhat difficult. Standards are
  undeniably good but one size doesn't fit all rule does apply here.
  Your package couldn't be used to represent big numbers. Little real
  work has been done on this so it's reasonable to expect progress or
  even some breakthough. 
 
 I thought there was some elegant way to express type level numbers
 using balanced ternary, but I can't find a reference to it at the
 moment.
 
Balanced ternary is useful for represeting signed integers.
Implementation of next, prev and basic arithmetic operations is not
very elegant

Some time ago I wrote implementation of type level numbers using binary
and balanced ternary encoding. Will upload to hackage soon. 
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Announce type-level-natural-number-1.0: Simple, Haskell 2010-compatible type level natural numbers

2010-07-30 Thread Alexey Khudyakov
On Fri, 30 Jul 2010 13:28:19 -0700
Gregory Crosswhite gcr...@phys.washington.edu wrote:
  Hey everyone,
 
 I am pleased to announce the release of the type-level-natural-number
 package, which implements natural numbers at the type level.  Although
 there are many packages on Hackage that implement type level natural
 numbers, this package is distinguished by its simplicity: it does not
 offer any operations other than predecessor, successor, and conversion
 to Int, and so the only Haskell extension it needs is EmptyDataDecls. 
 Thus, this package is compatible with Haskell 2010.
 
 The envisioned use case is for annotating types with natural numbers, so
 that extra functionality such as addition and subtraction of natural
 numbers is unnecessary.  Nothing is stopping someone from implementing
 this functionality, and in fact I may do so myself;  however, since such
 functionality is not needed merely for using these numbers, I decided to
 leave it out in order to avoid having to use non-Haskell 2010 extensions
 (especially UndecidableInstances).  In particular, a major motivation
 behind designing the package in this way is to make it more appealing as
 a standard means for representing natural number annotations in order to
 promote interoperability between libraries.
 
Type level addition doesn't require UndecidableInstances. It only
require TypeFamilies or fundeps. Here is implementation using type
families:

 type family Add n m :: *

 type instance Add Zero  Zero   = Zero
 type instance Add Zero (SuccessorTo n) = SuccessorTo n
 type instance Add (SuccessorTo n) m= SuccessorTo (Add n m)

Standard package is could be somewhat difficult. Standards are
undeniably good but one size doesn't fit all rule does apply here.
Your package couldn't be used to represent big numbers. Little real
work has been done on this so it's reasonable to expect progress or
even some breakthough. 

Maybe some generic inteface for conversion of different representation
of natural numbers would be good. Any suggestions

-- 
Alexey Khudyakov alexey.sklad...@gmail.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can we come out of a monad?

2010-07-30 Thread Alexey Khudyakov
On Fri, 30 Jul 2010 09:29:59 +0200
Stefan Holdermans ste...@vectorfabrics.com wrote:

 Jason,
 
  There is one case where you can break out of a monad without knowing which
  monad it is.  Well, kind of.  It's cheating in a way because it does force
  the use of the Identity monad.  Even if it's cheating, it's still very
  clever and interesting.
 
 How is this cheating?  Or better, how is this breaking out of a monad without
 knowing which monad it is?  It isn't. You know exactly which monad you're
 breaking out: it's the identity monad.  That's what happens if you put
 quantifiers in negative positions: here, you are not escaping out of an
 arbitrary monad (which you can't), but escaping out of a very specific monad.
 
No I think here we breaking out from _arbitrary_ monad. If monadic
function works for every monad then it must work for identity monad
too. Here is simplest form of purify function:

 purify2 :: (forall m . Monad m = m a) - a
 purify2 m = runIdentity m

This proves interesting fact. Value could be removed from monad if no
constrain is put on the type of monad. Moreover it Monad in this
example could be replaced with Functor or other type class

I wonder could this function be written without resorting to concrete
monad


-- 
Alexey Khudyakov alexey.sklad...@gmail.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Haskell at CERN

2010-07-27 Thread Alexey Khudyakov
Hello

I'm wondering is there any haskellers in CERN? Given quality
and usability of software there must be people looking for
better alternatives.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] HaTeX build failure

2010-07-23 Thread Alexey Khudyakov
On Fri, Jul 23, 2010 at 4:04 PM, Daniel Díaz lazy.dd...@gmail.com wrote:
 Hi,

 I uploaded a package, named HaTeX, to Hackage, but it gets a build failure:

 Any idea?

Cabal file has BOM in the beginning. Maybe it make parser choke...
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] cereal vs. binary

2010-07-03 Thread Alexey Khudyakov
On Sat, Jul 3, 2010 at 8:57 PM, braver delivera...@gmail.com wrote:
 I dump results of a computation as a Data.Trie of [(Int,Float)].  It
 contains about 5 million entries, with the lists of 35 or less pairs
 each.  It takes 8 minutes to load with Data.Binary and lookup a single
 key.  What can take so long?  If I change from compressed to
 uncompressed (and then decode), it's the same time...  It's not IO,
 CPU is loaded 100%.

 I'm now thinking of using cereal.  Given I have Data.Binary in place,
 what needs to be changed to work with cereal?  Is it binary-
 compatible?  How can one construct a cereal instance for Data.Trie?

I suspect Float instance is problem. Try to to the same with (Int,Int) pairs.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] cereal vs. binary

2010-07-03 Thread Alexey Khudyakov
On Sat, Jul 3, 2010 at 10:54 PM, Alexey Khudyakov
alexey.sklad...@gmail.com wrote:
 On Sat, Jul 3, 2010 at 8:57 PM, braver delivera...@gmail.com wrote:
 I dump results of a computation as a Data.Trie of [(Int,Float)].  It
 contains about 5 million entries, with the lists of 35 or less pairs
 each.  It takes 8 minutes to load with Data.Binary and lookup a single
 key.  What can take so long?  If I change from compressed to
 uncompressed (and then decode), it's the same time...  It's not IO,
 CPU is loaded 100%.

 I'm now thinking of using cereal.  Given I have Data.Binary in place,
 what needs to be changed to work with cereal?  Is it binary-
 compatible?  How can one construct a cereal instance for Data.Trie?

 I suspect Float instance is problem. Try to to the same with (Int,Int) pairs.

To clarify things.  If there is significant improvement in performance
(times, tens
of times) than Float's instance is indeed culprit.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Construction of short vectors

2010-06-28 Thread Alexey Khudyakov
On Mon, Jun 28, 2010 at 7:02 PM, Jake McArthur jake.mcart...@gmail.com wrote:
 On Sun, Jun 27, 2010 at 4:44 PM, Alexey Khudyakov
 alexey.sklad...@gmail.com wrote:
 Dependent types would be nice but there isn't anything usable out there.
 Newtype wrapper parametrized by type level number works fine so far.

 If you interested sources are available here:
 http://bitbucket.org/Shimuuar/nvector
 http://bitbucket.org/Shimuuar/type-numbers

 I haven't looked to see how complete your code is, but feel free to
 take over the vector-static [1] project if you wish to use some
 existing code. I haven't taken the time yet to say so on the Hackage
 page, but it's not currently being maintained.

I'm aware about this package but I didn't use it because it's completely
undocumented.

Also my code is a bit different. Vector is parametrized by two phantom type
parameters. One is vector length another is type of vector. I want to
be able to
differentiate between different vectors (euclidean vector and
polynomial coefficients
have different types)

There is also one rather wild idea. Since function for fixed vectors only wraps
function from vector in theory it could be possible to generate most of code.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Construction of short vectors

2010-06-27 Thread Alexey Khudyakov
On Fri, 25 Jun 2010 18:30:06 -0300
Felipe Lessa felipe.le...@gmail.com wrote:

 On Fri, Jun 25, 2010 at 12:41:48AM +0400, Alexey Khudyakov wrote:
  Then constructor like one below arise naturally. And I don't know how to 
  write
  them properly. It's possible to use fromList but then list could be 
  allocated
  which is obviously wasteful.
 
 Did you see the generated core?  I think you should give a try to
 the following simple code:
 
   import qualified Data.Vector.Generic as VG -- vector == 0.6.*
 
   vector2 :: Double - Double - Vec2D
   vector2 x y = Vec2D (VG.fromListN 2 [x,y])
 
I tryed to look at ghc core output but it was totally incomprehensible.
Is there any documentation about how to inspect and interpret generated
code, good practices etc?

  Another question is there any specific problems with short vectors? They 
  could
  be just 2 elements long. I mean performance problems
 
 Probably there will be more overhead than defining
 
   data Vec2D = Vec2D {-# UNPACK #-} !Double
  {-# UNPACK #-} !Double
 
 You should profile to see how much difference there is between
 those representations.
 
Sure. This price of code generality.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Core packages and locale support

2010-06-27 Thread Alexey Khudyakov
On Sun, 27 Jun 2010 10:28:49 +0300
Roman Beslik ber...@ukr.net wrote:

   On 27.06.10 10:17, Bulat Ziganshin wrote:
  Sunday, June 27, 2010, 11:07:47 AM, you wrote:
  Currently, FilePath is an alias for String.  Changing FilePath to a real
  type
  Just do not change FilePath, what may be simpler?
  if FilePath will become abstract type, it will break all programs
  that use it since they use it as String

 Hello, do you read me? I said: do not change FilePath.

It's no good either. Then there is no way to have both automatic
decoding of file names and working with file names with incorrect
encoding. 


-- 
Alexey Khudyakov alexey.sklad...@gmail.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Construction of short vectors

2010-06-27 Thread Alexey Khudyakov
On Sun, 27 Jun 2010 19:55:21 +1000
Roman Leshchinskiy r...@cse.unsw.edu.au wrote:

 On 25/06/2010, at 06:41, Alexey Khudyakov wrote:
 
  Then constructor like one below arise naturally. And I don't know how to 
  write
  them properly. It's possible to use fromList but then list could be 
  allocated
  which is obviously wasteful.
  
  vector2 :: Double - Double - Vec2D
  vector2 x y = ...
  -- Vec2D is some wrapper around Vector data type
 
 Your best bet is probably singleton x ++ singleton y. Unfortunately, GHC
 doesn't seem to provide any real way of specifying array literals.
 
Thank you for advice. And what about using ST monad?

 vector2 :: Double - Double - Vec2D
 vector2 x y = Vec2D $ create $ do a - new 2
   write a 0 x
   write a 1 y
   return a



  Another question is there any specific problems with short vectors? They
  could be just 2 elements long. I mean performance problems
 
 A data type like this one should be faster:
 
 data Vec2D = Vec2D {-# UNPACK #-} !Double {-# UNPACK #-} !Double
 
 Firstly, this needs one less indirection for accessing the
 components. Secondly, GHC's simplifier knows a lot more about algebraic data
 types than it does about arrays so the above definition will often lead to
 better optimisations. Whether or not the difference is significant probably
 depends on the program.
 
This is of course faster but what I really want is vectors with length
parametrized by type. This way I can write generic code. Uniform
representation is requirement for that. 

-- 
Alexey Khudyakov alexey.sklad...@gmail.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Construction of short vectors

2010-06-27 Thread Alexey Khudyakov
On Mon, Jun 28, 2010 at 12:00 AM, Alexander Solla a...@2piix.com wrote:

 On Jun 27, 2010, at 12:29 PM, Alexey Khudyakov wrote:

 This is of course faster but what I really want is vectors with length
 parametrized by type. This way I can write generic code. Uniform
 representation is requirement for that.

 You're going to need dependent types, or a similar construction, for that.

 Do We Need Dependent Types?
 http://www.brics.dk/RS/01/10/index.html

Dependent types would be nice but there isn't anything usable out there.
Newtype wrapper parametrized by type level number works fine so far.

If you interested sources are available here:
http://bitbucket.org/Shimuuar/nvector
http://bitbucket.org/Shimuuar/type-numbers

Thank you for the link. It seems that part of paper describes
applicative functors.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Core packages and locale support

2010-06-26 Thread Alexey Khudyakov
On Sat, 26 Jun 2010 10:14:50 -0300
Felipe Lessa felipe.le...@gmail.com wrote:
 On Sat, Jun 26, 2010 at 05:01:06PM +0400, Bulat Ziganshin wrote:
  but what you propose cannot be used in Windows at all! while current
  FilePath still works on Unix, with manual filenames en/decoding
 
 Now we got back on topic! :)
 
 The FilePath datatype is OS-dependent and making it abstract
 should be at least a first step.  If you got it from somewhere
 else where it is already encoded, then fine.  If you need to
 construct it, then you need to use a smart constructor.  If you
 need to show/print it, then you need to convert it to String.
 And so on.
 
It should solve most of problems I believe. But such change will break
a lot of programs maybe most of them. How could one introduce such a
change? One variant is to create new hierarchy and gradually deprecate
old.

Also same problem affect command line arguments and process module.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Construction of short vectors

2010-06-24 Thread Alexey Khudyakov
Hello, cafe

I have question about vector package.

Currently I'm playing with data types which are isomorphic to vectors of fixed
length. Think about vector in N-dimensional space, list of parameters to
function R^n → R, set of measurements with uncertainties, etc. They have
different semantics but exactly the same representation and it's often
advantageous to think about them as N-dimensional vectors.

Then constructor like one below arise naturally. And I don't know how to write
them properly. It's possible to use fromList but then list could be allocated
which is obviously wasteful.

 vector2 :: Double - Double - Vec2D
 vector2 x y = ...
 -- Vec2D is some wrapper around Vector data type

Another question is there any specific problems with short vectors? They could
be just 2 elements long. I mean performance problems
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] What is Haskell unsuitable for? Dis-functional programming!

2010-06-17 Thread Alexey Khudyakov
On Thu, 17 Jun 2010 13:45:16 -0400
cas...@istar.ca wrote:

 :)
 
Objection!

http://hackage.haskell.org/package/BASIC
A simplified version of the original BASIC embedded in Haskell. 

-- 
Alexey Khudyakov alexey.sklad...@gmail.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Reporting a problem with binary-0.5

2010-06-04 Thread Alexey Khudyakov
On Fri, Jun 4, 2010 at 8:02 PM, Pete Chown 1...@234.cx wrote:
 I've been trying to get in touch with the maintainers of the Binary package,
 to report an issue.  When I emailed the addresses given on Hackage, I got an
 automated response saying I had used an address that was no longer current.

 I don't want to put pressure on anyone to fix my bug -- I didn't pay
 anything for Binary, so it wouldn't be fair for me to have that kind of
 expectation.  At the same time, I don't really want my bug report to go
 missing just because someone's email address has changed.  Does anyone know
 who I should be talking to?  Or is there a bug tracker for the Hackage
 packages somewhere?

 I noticed this problem when I ran into some trouble with the network-dns
 package.  It would hang up as soon as I tried to send a query. Eventually I
 traced the problem to the binary module, and reduced it to this short test
 case:

 module Main where

 import qualified Data.Binary.Get as G
 import qualified Data.ByteString.Lazy as B

 main = do
  urandom - B.readFile /dev/urandom
  let urandomParser :: G.Get [Int]
      urandomParser = do
        v - G.getWord32be
        rest - urandomParser
        return $ fromIntegral v : rest
      seeds = G.runGet urandomParser urandom

  print $ take 4 seeds

This issue was discussed on the list before. Get monad definition
was changed in binary 0.5.0.2. It was made strict and evaluation
of result of runGet is forced. This increased performance but
broke programs which relies on lazyness to work.

Here is code I use to work around this issue:

 runGetStream :: Get a - ByteString - [a]
 runGetStream getter bs = unfoldr step bs
 where
   step bs = case runGetState getOne bs 0 of
   (Nothing, _,   _   ) - Nothing
   (Just x,  bs', off') - Just (x, bs')
   getOne = do empty - isEmpty
   if empty
 then return Nothing
 else Just $ getter
 ...
 seeds = runGetStream (fromInteger $ getWord64be) urandom
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Reporting a problem with binary-0.5

2010-06-04 Thread Alexey Khudyakov
On Fri, Jun 4, 2010 at 8:31 PM, Alexey Khudyakov
alexey.sklad...@gmail.com wrote:
 Here is code I use to work around this issue:

Forgot to mention. This code checks for end of input. Your data is
infinite so you simplify
definition if you like
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell for Physicists

2009-12-04 Thread Alexey Khudyakov
2009/12/4 Roman Salmin roman.sal...@gmail.com:
 On Fri, Dec 04, 2009 at 01:43:42PM +, Matthias Görgens wrote:
   _So my strong opinion that solution is only DSL not EDSL_

 Why do you think they will learn your DSL, if they don't learn any
 other language?
  I didn't said that they didn't learn any language. They learn languages,
 but
  only part that is necessary to do particular task.
   f.e. ROOT CINT(C++ interpreter) didn't distinguish object from pointer to
 object, i.e.
   statement h.ls(); works as well as h-ls(); independently of either h has
 type TH1F or TH1F*,
   so beginning ROOT user didn't need know what is pointer, memory management
 helps him.
  But early or latter one need to write more complicated code,
  then one need to spend months to reading big C++ books, and struggling with
 compilers errors, segfaults etc..^(1) (instead of doing assigned task!) or,
 what is more usually, trying Ad hoc methods for writing software.
  So people will learn DSL because:
   1. DSL is simpler than general purpose language
   2. DSL describe already known domain for user, (one probably don't need
 monads, continuations, virtual methods, template instantiation etc...etc...)
 so learning is easy, and didn't consume much time.

  And if your DSL includes general purpose stuff, like
 functions, control structures, data structures, you'll re-invent the
 wheel.  Probably porly.
  You didn't need to reinvent the wheel, because you DSL compiler can
 produce Haskell code:
DSL - General Purpose Language - Executable
  And ever if you do, it saves allot of time of experts.

  Roman.

 (1) In Haskell this probably will sound like: reading allot of small
 tutorials and articles, grokking monads,
struggling with type-check errors, infinite loops, laziness, etc...

There is other side. As Matthias Görgens mentioned earlier

1. One have to reinvent control structures. Multiple times. Lets assume that
compiler would translate DSL to haskell code. But DSL's expressions which
convert into haskell control structures are DSL's control structures.

2. There would be more than one DSL. If they are all EDSL there is no real
problems with combining them in one program if necessity arises. Probably
there would be ways to combine them if they are DSL but they will require
expertise and most likely dirty hacks.

2.1 And all of them will have different conrol structures, abstraction
mechanisms.

3. Turing tarpit. Users will constantly require more power and features in
DSL. Most likely DSL designers wouldn't be great language designers so
DSL will turn into utter mess.

4. One have all power (and libraries of host languages). Of course if he is
able to utilize it.

This is tradeoff between power and simplicity. If one have too much simplicity
he is not able to solve difficult problems. If one have too much power at
expense of simplicity he has to struggle with tool to have thing done.
And it's possible to sacrifice simplicity and don't gain any power.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Data.Binary and error handling

2009-12-03 Thread Alexey Khudyakov
On Fri, Nov 27, 2009 at 10:36 PM, Mark Lentczner ma...@glyphic.com wrote:
 I'm in the same quandary:

 Data.Binary from the binary package has no error handling
 Data.Serialize from the cereal package uses only strict ByteString

 I was going to add error handling to Binary as a weekend project (it isn't 
 that hard), but when I contacted the developers of binary, I was pointed at 
 cereal. But as my project can parse multi-megabyte objects off the wire, I 
 really want lazy ByteString support.

 I understand from the cereal creators that lazy ByteStrings are not in the 
 future of cereal, since they got a big speed boost by going to strict 
 ByteStrings only.

 I understand that Bryan O'Sullivan might have done work on adding errors to 
 Binary... Bryan? If that's available, can we get it? If not, shall I do the 
 work to add error handling?  It's a long weekend... I've got time!

As an experiment I ported error handling from cereal to binary. It
does work, passes all tests shipped
with binary. Perfomance became worse. According to benchmarks shipped
with binary I observed ~25%
perfomance drop. However when I ported my program I have 40% speedup.
I think it's because I removed
code which work around lack error handling and replaced with error
handling in Get monad

As for strictess concerns. Patch doesn't seem to change strictess from
current state. At least my program
which uses very big inputs works without any changes.

Comments and suggestions are welcome
diff -r 8cb04f000736 src/Data/Binary/Get.hs
--- a/src/Data/Binary/Get.hs	Thu Dec 03 00:40:24 2009 +0300
+++ b/src/Data/Binary/Get.hs	Fri Dec 04 01:24:19 2009 +0300
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fglasgow-exts #-}
+{-# LANGUAGE BangPatterns #-}
 -- for unboxed shifts
 
 -
@@ -26,6 +27,7 @@
 -- * The Get type
   Get
 , runGet
+, runGetE
 , runGetState
 
 -- * Parsing
@@ -103,15 +105,23 @@
 data S = S {-# UNPACK #-} !B.ByteString  -- current chunk
L.ByteString  -- the rest of the input
{-# UNPACK #-} !Int64 -- bytes read
+ 
+type Failure   r = String - Either String (r, S)
+type Success a r = S - a - Either String (r, S)
 
--- | The Get monad is just a State monad carrying around the input ByteString
--- We treat it as a strict state monad. 
-newtype Get a = Get { unGet :: S - (# a, S #) }
+-- | The Get monad is an Exception and State monad.
+newtype Get a = Get { unGet :: forall r. S
+- Failure   r
+- Success a r
+- Either String (r, S) }
 
 instance Functor Get where
-fmap f m = Get (\s - case unGet m s of
- (# a, s' #) - (# f a, s' #))
-{-# INLINE fmap #-}
+fmap p m = Get (\s0 f k - unGet m s0 f (\s a - k s (p a)))
+
+instance Monad Get where
+return a = Get (\s0 _ k - k s0 a)
+m = g  = Get (\s0 f k - unGet m s0 f (\s a - unGet (g a) s f k))
+fail = failDesc
 
 #ifdef APPLICATIVE_IN_BASE
 instance Applicative Get where
@@ -119,29 +129,18 @@
 (*) = ap
 #endif
 
--- Definition directly from Control.Monad.State.Strict
-instance Monad Get where
-return a  = Get $ \s - (# a, s #)
-{-# INLINE return #-}
-
-m = k   = Get $ \s - case unGet m s of
- (# a, s' #) - unGet (k a) s'
-{-# INLINE (=) #-}
-
-fail  = failDesc
-
-instance MonadFix Get where
-mfix f = Get $ \s - let (a,s') = case unGet (f a) s of
-  (# a', s'' #) - (a',s'')
-in (# a,s' #)
+--instance MonadFix Get where
+--mfix f = Get $ \s - let (a,s') = case unGet (f a) s of
+--  (# a', s'' #) - (a',s'')
+--in (# a,s' #)
 
 
 
 get :: Get S
-get   = Get $ \s - (# s, s #)
+get = Get (\s0 _ k - k s0 s0)
 
 put :: S - Get ()
-put s = Get $ \_ - (# (), s #)
+put s = Get (\_ _ k - k s ())
 
 
 --
@@ -176,24 +175,40 @@
 (x:xs') - S x (B.LPS xs')
 #endif
 
+finalK :: Success a a
+finalK s a = Right (a, s)
+
+failK :: Failure a
+failK s = Left s
+
 -- | Run the Get monad applies a 'get'-based parser on the input ByteString
 runGet :: Get a - L.ByteString - a
-runGet m str = case unGet m (initState str) of (# a, _ #) - a
+runGet m str = case unGet m (initState str) failK finalK of
+ Right (a, _) - a
+ Left message - error message
 
 -- | Run the Get monad applies a 'get'-based parser on the input
 -- ByteString. Additional to the result of get it returns the number of
 -- consumed bytes and the rest of the input.
 runGetState :: Get a - L.ByteString - Int64 - (a, L.ByteString, Int64)
 runGetState m str off =
-

[Haskell-cafe] Data.Binary and error handling

2009-11-27 Thread Alexey Khudyakov
Hello

 Is there any plans to add error handling for binary? When it comes to
binary parsing most awkward part is error handling

I presume answer will be like there are some vague plans but no one
to implement them so the second question how could it be done?

Naive implementation of error handliing which converts Get monad into
hybrid of state monad and error monad (Either like) gives about 5
times slowdown.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] poor perfomance of indexU in uvector package

2009-11-16 Thread Alexey Khudyakov
On Sun, Nov 15, 2009 at 8:59 PM, Don Stewart d...@galois.com wrote:
 alexey.skladnoy:
 I found that perfomace of indexU is very poor and it is not fast O(1)
 operation which is very surprising. Here is some benchmarcking I've
 done. Everything compiled with -O2

 You're using the streamed version when its not fusing. Use the
 non-streaming direct implementation exported from Data.Array.Vector.UArr

 This is really an API bug, but I've not had time to sanitize the use.

Probably this should be stated more explicitly in documentation. This is
_very_ unexpected and confusing behaviour.

Also I don't quite understand nature of bug. Is this missing export or
wrong function is exported. And is streamed version of idexU useful
 and in which way?


On Sun, Nov 15, 2009 at 9:11 PM, Thomas DuBuisson
thomas.dubuis...@gmail.com wrote:
 The documentation explicitly says indexU is O(n) - no need for so much
 testing to rediscover that fact.  When I needed a contiguous block of
 values in UArr, I just relied on sliceU to acquire the block and
 performed a foldU.

Problems begin when you need non-contiguous block. Easiest way to so
is indexing.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] poor perfomance of indexU in uvector package

2009-11-15 Thread Alexey Khudyakov
Hello

This post meant to be literate haskell.

I found that perfomace of indexU is very poor and it is not fast O(1)
operation which is very surprising. Here is some benchmarcking I've
done. Everything compiled with -O2

Code below converts square 2D array to list of 1D arrays. Summation of
array contents is done in force evaluation

 import Control.Monad
 import Control.Monad.ST
 import Data.Array.Vector
 import System

 arr :: Int - UArr Double
 arr n = toU $ map fromIntegral [1 .. n*n]


This is fastest function. It slice arrays along another direction and used
mainly as upper bound of speed
 sliceY :: Int -  UArr Double - [UArr Double]
 sliceY n a = map (\i - sliceU a (i*n) n) [0 .. n-1]


Naive implementation using lists and index lookup.
  2.15 second for 200*200 array
 sliceXlist :: Int - UArr Double - [UArr Double]
 sliceXlist n a = map mkSlice [0 .. n-1]
 where
   mkSlice x = toU $ map (\y - indexU a (x + y*n)) [0 .. n-1]

Similar implementation in ST monad and it uses indexU too.
  2.14 seconds for 200*200 array
 sliceXst :: Int -   UArr Double - [UArr Double]
 sliceXst n a = map mkSlice [0 .. n-1]
 where
   mkSlice x = runST $ do arr - newMU n
  forM_ [0 .. n-1] $ \y - writeMU arr y (indexU a 
 (y*n + x))
  unsafeFreezeAllMU arr

This implementation avoids use of indexU by copying entire
2D array into mutable array and using it for lookup. Surprisingly
it outperform previsious implementations for sufficiently big n
  1.19 seconds for 200*200 array
 sliceXcopy :: Int -  UArr Double - [UArr Double]
 sliceXcopy n a = map mkSlice [0 .. n-1]
 where
   mkSlice x = runST $ do arr - newMU n
  cp  - newMU (n*n)
  copyMU cp 0 a
  forM_ [0 .. n-1] $ \y - writeMU arr y = 
 readMU cp (y*n + x)
  unsafeFreezeAllMU arr

This is another  implementation with lists which convert whole
array to list and picks appropriate element it. It is fastest implementation
so far.
0.039 seconds for 200*200 array
 sliceXlistfast :: Int - UArr Double - [UArr Double]
 sliceXlistfast n a = map mkSlice [0 .. n-1]
 where
   takeEvery n [] = []
   takeEvery n (x:xs) = x : takeEvery n (drop (n-1) xs)
   mkSlice x = toU $ takeEvery n . drop x $ fromU a




 
 main :: IO ()
 main = do
   [str,a] - getArgs
   let n = read str
   case a of
   y- print $ sum $ map sumU (sliceY n (arr n))
   list - print $ sum $ map sumU (sliceXlist n (arr n))
   lf   - print $ sum $ map sumU (sliceXlistfast n (arr n))
   st   - print $ sum $ map sumU (sliceXst   n (arr n))
   copy - print $ sum $ map sumU (sliceXcopy n (arr n))
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] poor perfomance of indexU in uvector package

2009-11-15 Thread Alexey Khudyakov
On Sun, Nov 15, 2009 at 5:50 PM, Felipe Lessa felipe.le...@gmail.com wrote:
 On Sun, Nov 15, 2009 at 03:00:34PM +0300, Alexey Khudyakov wrote:
 Naive implementation using lists and index lookup.
   2.15 second for 200*200 array
  sliceXlist :: Int - UArr Double - [UArr Double]
  sliceXlist n a = map mkSlice [0 .. n-1]
  where
mkSlice x = toU $ map (\y - indexU a (x + y*n)) [0 .. n-1]

 Have you tried something like

  mkSlice x = mapU (\y - indexU a (x + y*n)) $ enumFromToU 0 (n-1)

 I guess it should be a lot faster :).

No it doesn't. There is no significant difference between two variant above.
I think any program which uses indexU will be slowed to crawl.
Seems like a bug for me.


   Another implementation you may try is

  a' = mapU (\(i :*: x) - (i `mod` n) :*: x) (indexedU a)
  mkSlice j = fstU $ filterU (\(i :*: x) - i == j) a'

This one is fastest so far


 Also, I would recomend using criterion.

I tried to do so.. But it depends on gtk2hs and it is too difficult
to install
___
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] [uvector] derive UA instance for newtype

2009-09-24 Thread Alexey Khudyakov
On Wed, Sep 23, 2009 at 11:19 PM, Daniel Peebles pumpkin...@gmail.com wrote:
 I believe this is a bug that was introduced in 6.10.2 (it definitely
 worked in 6.10.1) that has since been fixed in HEAD. This newtype
 deriving issue also prevents the uvector testsuite from running at the
 moment.

Yes. It works in 6.10.1
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] XMonad and NetworkManager?

2009-06-29 Thread Alexey Khudyakov
On Mon, Jun 29, 2009 at 12:58 PM, Ketil Maldeke...@malde.org wrote:

 Hi,

 A bit off-topic, but this is the café, after all...

 Like many here, I run XMonad as my window manager on top of Linux.
 On - at least my brand of - Linux, networking is generally handled by
 NetworkManager, which really needs its associated applet (nm-applet)
 to work properly.  While I discovered trayer, which at least let me
 run nm-applet without dragging in most of Gnome, it still drags in
 some of the bloat, and interacts a bit poorly with the rest of the
 system (temporarily locks up the screen, transparency doesn't work,
 positions itself awkwardly, needs gconfd at incovinient times..)

 So: has anybody tried better alternatives to NetworkManager and
 nm-applet?  Wicd, say?  Or something that can integrate with dzen?

I use wicd to manage wireless connections for about three month and
I'm pretty happy with it. It seems to be much saner than network manager.
Didn't any serious problems with it.

From version 1.6 they introduced curses interface, so you don't need
applet or even X.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANNOUNCE: Runge-Kutta library -- solve ODEs

2009-04-19 Thread Alexey Khudyakov
 I have so far only tested it with ghc 6.8.3 on MacOS 10.3.9 (powerPC),
 but I know of no reason why it wouldn't work with other versions and
 OSs.

It breaks on Linux (and all unices) because name of file in tarball is
'rungekutta.hs' not
'RungeKutta.hs' as required. In other words: god blame
case-insensitive file systems.

After renaming everything works just fine.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How to use Unicode strings?

2008-11-22 Thread Alexey Khudyakov

 This upsets me. We need to get on with doing this properly. The
 System.IO.UTF8 module is a useful interim workaround but we're not using
 it properly most of the time.

 ... skipped ...

 The right thing to do is to make Prelude.putStrLn do the right thing. We
 had a long discussion on how to fix the H98 IO functions to do this
 better. We just need to get on with it, or we'll end up with too many
 cases of people using System.IO.UTF8 inappropriately.

But this bring question what the right thing is? If locale is UTF8 or system
support unicode some other way - no problem, just encode string properly.
Problem is how to deal with untanslatable characters. Skip? Replace with
question marks? Anything other? Probably we need to look how this is
solved in other languages. (Or not solved)

And this problem related not only to IO. It raises whenever strings cross
border between haskell world and outside world. Opening files with unicode
names, execing, etc.

For example:
Prelude readFile файл
*** Exception: D09;: openFile: does not exist (No such file or directory)
Prelude executeFile echo True [Сейчас сломается] Nothing
!59G0A A;05BAO

Althrough it's possible to work around using encodeString/decodeString from
Codec.Binary.UTF8.String it won't work on non-UTF8 systems. It's not only
neandertalian systems with one-byte locales, windows AFAIK uses other
unicode encoding.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Histogram creation

2008-11-10 Thread Alexey Khudyakov
Hello!

I'm tryig to write efficient code for creating histograms. I have following
requirements for it:

1. O(1) element insertion
2. No reallocations. Thus in place updates are needed.


accumArray won't go because I need to fill a lot of histograms (hundrends) from
vely long list of data (possibly millions of elements) and it will traverse
input data for each histogram.

It seems that I need to use mutable array and/or ST monad or something else.
Sadly both of them are tricky and difficult to understand. So good examples or
any other ideas greatly appreciated.

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