Re: [Haskell-cafe] converting prefixes of CString - String

2011-04-26 Thread Eric Stansifer
 Let 'c2h' convert CStrings to Haskell Strings, and 'h2c' convert
 Haskell Strings to CStrings.  (If I understand correctly, c2h . h2c
 === id, but h2c . c2h is not the identity on all inputs;

 That is correct.  CStrings are 8-bits, and Haskell Strings are 32-bits.  
 Converting from Haskell to C loses information, unless you use a multi-byte 
 encoding on the C side (for instance, UTF8).

So actually I am incorrect, and h2c . c2h is the identity but c2h . h2c is not?

 I suggest you look at the utf8-string package, for instance 
 Codec.Binary.UTF8.String.{encode,decode}, which convert Haskell strings 
 to/from a list of Word8, which can then be transferred via the FFI to 
 wherever you like.

This package was very helpful;  I looked at the source to see how the
utf8 encoding was done.  It looks as if the functionality I want is
technically feasible but not implemented yet;  it shouldn't be too
much trouble to implement it myself, by imitating the existing
'decode' function but changing its behavior when it runs out of input
in the middle of a utf8-character.  Also key is the property
s1 ++ s2 == decode (encode s1)) ++ decode (encode s2))
holds.

Thanks,
Eric

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


[Haskell-cafe] converting prefixes of CString - String

2011-04-25 Thread Eric Stansifer
I have been reading Foreign.C.String but it does not seem to provide
the functionality I was looking for.

Let 'c2h' convert CStrings to Haskell Strings, and 'h2c' convert
Haskell Strings to CStrings.  (If I understand correctly, c2h . h2c
=== id, but h2c . c2h is not the identity on all inputs;  or perhaps
c2h is not defined for all CStrings.  Probably this is all locale
dependent.)

I have an infinite Haskell String transferred byte-wise over a
network;  I would like to convert some prefix of the bytes received
into a prefix of the String I started with.  However, if I understand
correctly, if s is a Haskell String it is not necessarily true that
c2h (take n (h2c s)) is a prefix of s for all n.  So I have two
questions:

Given a CString of the form cs = take n (h2c s), how do I know
whether c2h cs is a prefix of s or not?  Is there a way to recognize
whether a CString is valid as opposed to truncated in the middle of
a code point, or is this impossible?  Better yet, given a CString cs
= take n (h2c s), is there a way to find the maximal prefix cs' of cs
such that c2h cs' is a prefix of s?

If s == s1 ++ s2, is it necessarily true that s == (c2h (h2c s1)) ++
(c2h (h2c s2))?  If so, then I can perform my conversion a bit at a
time, otherwise I'd need to start from the beginning of the cstring
each time I receive additional data.

In practice, I think my solution will come down to restricting my
program to only using the lower 128 characters, but I'd like to know
how to handle this problem in full generality.

Thanks,
Eric

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


[Haskell-cafe] thread safety, IO arrays, and IO refs

2010-12-31 Thread Eric Stansifer
Hello,

I wish to use a mutable array in multiple threads.  Can IO arrays be
used in any thread, or only the thread they are created in?  (So if I
create an IO array in one thread, pass it to another via an MVar, can
I read / edit it in that other thread?)  Similarly about IORefs... can
they be used across threads?

(Obviously I will need to manage locking myself if I use an IO ref or array.)

Are there any good resources on concurrency in Haskell that would
answer questions similar to these?  I've been learning by reading the
ghc library documentation, but of course it's not comprehensive.  The
online tutorials I've seen aren't so in-depth, either.

Thanks,
Eric

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


Re: [Haskell-cafe] thread safety, IO arrays, and IO refs

2010-12-31 Thread Eric Stansifer
I tried a quick test with an IOArray, so I know that at least one time
it works.  I don't know enough of the internals of IO and IOArray to
be able to extrapolate;  there could be some race condition hidden
internally if IO is misused.

Thanks,
Eric

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


Re: [Haskell-cafe] Not in scope: type constructor or class `Map'

2010-12-30 Thread Eric Stansifer
Because Data.Map is imported qualified, any symbols in it (including
Map) needs to be qualified:

type Bindings = Map.Map String Int


A standard idiom is to do import like so:

import qualified Data.Map as Map
import Map (Map)

so that the Map symbol itself does not need qualification.

Eric

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


[Haskell-cafe] SampleVar semantics, documentation vs. source

2010-12-29 Thread Eric Stansifer
Hi,

doc:  
http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.0.0/Control-Concurrent-SampleVar.html
source:  
http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.0.0/src/Control-Concurrent-SampleVar.html

The documentation for Control.Concurrent.SampleVar implies that a
SampleVar is either filled or empty.  The source code suggests
that there are three possible states:  full (when readers == 1),
empty (when readers == 0), and empty with blocked readers (when
readers  0).  In particular, the isEmptySampleVar function,

isEmptySampleVar :: SampleVar a - IO Bool
isEmptySampleVar (SampleVar svar) = do
  (readers, _) - readMVar svar
  return (readers == 0)

returns false in the third state, when readers  0.  Can someone
clarify the semantics of SampleVar?

Thanks,
Eric

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


[Haskell-cafe] lhs syntax highlighting in vim

2008-06-10 Thread Eric Stansifer
Hello,

The syntax highlighting file for literate haskell in vim says that its
maintainer is haskell-cafe@haskell.org, so hopefully one of you will
find this relevant.

In literate haskell files, vim optionally highlights the non-code text
according to TeX markup.  The syntax highlighting file looks for key
phrases (e.g., \documentclass) to decide whether to use TeX markup
highlighting;  but it (erroneously, in my opinion, and at variance
with the documentation) will use TeX markup highlighting on any lhs
file that contains the '%' character anywhere in it.  The bug is in
line 74 of version 1.01 of the lhaskell.vim syntax highlighting file.

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


Re: [Haskell-cafe] Newbie: State monad example questions

2008-05-22 Thread Eric Stansifer
 So, are there any other simple motivating examples that show what
 state is really good for?

Here's an example from some code that I'm (trying to) write;  I am
writing a DSL for the Povray Scene Description Language.  This part of
my program creates a `String' which holds a piece of Povray SDL code.
I am using the state to keep track of an infinite list of unique
identifiers -- when I use an identifier I would like to avoid reusing
the same one later.

 type Identifier = String
 type Identifiers = [Identifier]
 all_identifiers :: Identifiers
 all_identifiers = map (\n - var ++ show n) [0, 1..]

 next_id :: State Identifiers Identifier
 next_id = do
   (a:as) - get
   put as
   return a

I define a function let_ so that if a user of my code writes something like:

 let_ value expr

For example, if a user said:

 let_ (vector (0, 0, 0))
   (\origin -
 let_ (vector (1, 2, 3))
   (\p -
   union [box origin p, sphere origin (float 1), cylinder origin p 
 (float 0.5)]))

it should be analogous to:

 union [box (vector (0, 0, 0)) (vector (1, 2, 3)), sphere (vector (0, 0, 0)) 
 (float 1), cylinder (vector (0, 0, 0)) (vector (1, 2, 3)) (float 0.5)]

(Cf. http://www.haskell.org/pipermail/haskell-cafe/2008-February/039639.html
for details on what I'm trying to do here, but it has nothing to do
with my example usage of a state monad.)

In my definition of let_, I extract a fresh, unused identifier which
is assigned to the value of value.

 type Code x = State Identifiers String
 let_ :: Code x - (Code x - Code y) - Code y
 let_ m_value m_expr = do
   id - next_id
   value - m_value
   expr - m_expr (return id)
   return (#declare  ++ id ++  =  ++ value ++ ;\n ++ expr)

Either of the expressions m_value or m_expr may require their own
unique identifiers, but the State monad takes care of threading my
`Identifiers' state so that the same identifier will not be used more
than once.

Later on, when I made a more sophisticated version of `Identifiers'
which kept of track of multiple different namespaces from which
identifiers could come, I only had to modify `next_id' without having
to worry about whether I would have to make changes in other parts of
the program (although I believe further changes would not have been
necessary even if I had not used State monads, the modularity of the
code is much more obvious when using the State monad instead of
explicitly writing out the state that is being passed around).

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


Re: [Haskell-cafe] Short circuiting and the Maybe monad

2008-05-18 Thread Eric Stansifer
 Since a tree is a kind of container, yes, it should be a monad. [I'm still
 not really sure whether it's useful.]

I have a use for the tree monad -- well, I have a use for the monadic
`join' operation (but I don't use any of the monadic operations other
than `return').

My program is making a file.  It stores the lines in the file (I need
the individual lines, for operations like indent all lines by four
spaces):

* type File = [Line]

And each line is a ordered collection of String s, waiting to be concatenated:

* type Line = [String]

At the end of the day I need one long string:

* finish :: File - String
* finish file = concat (concat file)

(I'm eliding dealing with endlines, etc.)

But elsewhere in my program, I would like to have an O(1) (++)
operation, i.e., I would like to be able to do line1 ++ line2 and
file1 ++ file2 in O(1) time.  So I use a Tree a instead of [a]:

 type File = Tree Line
 type Line = Tree String
 finish file = concat (tree_to_list (tree_flatten file))

Admittedly, I'm not really doing anything actually monadic here -- I
just happen to be using the `join' operation.  I am sure others can
come up with better examples.

While we're at it, an example use for the ((-) a) monad.  For any set
S and ring R, the abelian group of functions f :: S - R is a free
module (in the mathematical sense of the word module) over the ring
R.  The group and module operations are easily defined in terms of the
monadic operations:

 data FreeModule s r = FreeModule (s - r)
 instance Functor (FreeModule s) where ...
 instance Monad (FreeModule s) where ...
 instance Ring r = Group (FreeModule s r) where
   (+) m1 m2 = liftM2 (+) m1 m2
   negative m = fmap negative m
   zero = return zero

 instance Ring r = Module r (FreeModule s r) where
   r * m = fmap (r *) m

(Here I write `r * m' to mean the module element `m' left-multiplied
by the ring element `r'.)

I have another implementation of FreeModule which specializes S to the
natural numbers:  but the set of functions f :: \mathbb{N} - R are
isomorphic with f :: [R] (provided we only permit infinite lists), in
the same way that Dave Menendez describes how f :: Bool - a is
isomorphic to f :: Diag a.  Under this isomorphism, we translate the
monadic operations from ((-) \mathbb{N}) to monadic operations on
lists -- but the resulting monad is different from the usual list
monad (where join = concat is the structure flattening operation).
After all, the `concat' operation is pretty boring if you only permit
infinite lists (for then `concat' is the same as `head').

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


Re: [Haskell-cafe] Short circuiting and the Maybe monad

2008-05-18 Thread Eric Stansifer
 I have another implementation of FreeModule which specializes S to the
 natural numbers:  but the set of functions f :: \mathbb{N} - R are
 isomorphic with f :: [R] (provided we only permit infinite lists), in
 the same way that Dave Menendez describes how f :: Bool - a is
 isomorphic to f :: Diag a.

This is what I get for reading only the first half of Dave Menendez's
email... I saw the words Here's a more complex example and skipped
the rest.  Read his explanation -- it's a lot more coherent than mine.

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


Re: [Haskell-cafe] Re: Endianess

2008-05-14 Thread Eric Stansifer
 So I've always wondered, if you are writing down a number being dictated
 (slowly) by someone else, like 234, do you write the 2, then leave space and
 write the 4, then go back and fill in with 3? Or do you push the 4 onto the
 stack until the 3 arrives, and write 34 at once.

My German professor told us a story, set in WWII:  Two British pilots
shot down behind enemy lines, who had received very thorough training
on German culture, current sports, etc., successfully blended in with
the native Germans for some time until someone noticed them in a cafe
writing down the sum on their bill in left-to-right order.  They were
summarily shot.

Not that I have any idea whether this is based on truth or not, or
whether Germans, in fact, write the last two digits in reverse order.

Also, Claus's reply gives me a headache.

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


[Haskell-cafe] Type unions

2008-05-10 Thread Eric Stansifer
I have been trying to write a DSL for Povray (see www.povray.org) in
Haskell, using the technique of:
http://okmij.org/ftp/papers/tagless-final-APLAS.pdf
with some inspiration taken from
http://okmij.org/ftp/Haskell/DSLSharing.hs

The Povray Scene Description Language is a very declarative language,
with few high level constructs (even loops take a bit of work) --
which is why I'm putting it in Haskell.

At one point, I needed a varargs function for the DSL, a function f
:: b - a - b dressed up to take a variable number of 'a's, known at
compile time.  This was easy enough:

 data Nil a = Nil
 data Cons b a = a ::: b a
 infixr 1 :::

 class VarArgs v where
   apply_args :: (s - a - s) - s - v a - s

 instance VarArgs Nil where
   apply_args _ start _ = start

 instance VarArgs b = VarArgs (Cons b) where
   apply_args f start (a ::: b) = apply_args f (f start a) b

The solution is quite workable:  I can simply write the following, and
I believe the summation is expanded out at compile-time:

 apply_args (+) 0 (2 ::: 3 ::: 8 ::: 1 ::: (-3) ::: Nil)

But I found I also needed a function to take a union type -- that is,
the function would either take an argument of type T1, or of type T2,
known at compile time.  I tried a similar technique as I tried with
varargs, and unfortunately ended up with this:

 data LeftOf a b = L a
 data RightOf a b = R b

 class Union u where
   apply_union :: (a - c) - (b - c) - (u a b) - c

 instance Union LeftOf where
   apply_union f _ (L a) = f a

 instance Union RightOf where
   apply_union _ g (R b) = g b

 type A = Integer
 type B = String
 type C = ()

 type Union_ABC u1 u2 = u1 A (u2 B C)

 f_A = show . (+ 3)
 f_B = reverse
 f_C = const unit

 f :: (Union u1, Union u2) = Union_ABC u1 u2 - String
 f = apply_union f_A (apply_union f_B f_C)

 main = do
   putStrLn $ f $ (L 6 :: Union_ABC LeftOne LeftOne)
   putStrLn $ f $ R (L hello, world)
   putStrLn $ f $ R (R ())

Notice a lot of ugliness in my example:  e.g., the definition of f,
the type signature of f (I can't move the context into the
type-synonym Union_ABC), creating objects of the union type, and the
unpleasant surprise that I needed to provide the type of 'L 6'.  This
solution is very not-scalable:  the Povray SDL is a messy language,
and for my DSL I would need approximately 20 or 30 such unions, each a
union of about 20 types (admittedly with a lot of overlap from union
to union).

I think the solution is to abandon the lofty ideal of statically
determining argument types;  instead have a universal type with tags
to distinguish types dynamically:

 data Universal = UA A | UB B | UC C
 f :: Universal - String
 f (UA a) = f_A a
 f (UB b) = f_B b
 f (UC c) = f_C c

 main2 = do
   putStrLn $ f $ UA 6
   putStrLn $ f $ UB hello, world
   putStrLn $ f $ UC ()

...but I'm not ready to give up hope yet.  Suggestions please?

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


Re: [Haskell-cafe] Type unions

2008-05-10 Thread Eric Stansifer
 Try making a type class for the functions.  That will allow you both varargs
 and unions.
 Have a look at Text.Printf.

Thank you -- looking at Printf was very helpful.  My syntax is much
happier as a result.

I also see now that I am approaching the problem from the wrong
direction -- that by writing a whole slew of functions whose behavior
depends arbitrarily upon their argument type, I would need to code the
desired behavior for each function and each argument type;  getting
hung up on making the syntax manageable hid this realization from me.
The solution is for me to try much harder to extract common behavior
across argument types and only code special cases when truly
necessary.

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


Re: [Haskell-cafe] Maybe a, The Rationale

2008-05-10 Thread Eric Stansifer
 IME nullable by default is one of the biggest
 sources of runtime crashes in high level OOP languages like C#, which is a
 shame because it really isn't that difficult to statically eliminate the
 vast majority of them, especially when you're sort of hand-waving the
 semantics of your language anyway and don't require it to be super
 rigorous...

I definitely agree.  After I'd been learning Haskell for 6 months and
then wrote a program in Java  C++, almost the first thing I did was
code up a generic MaybeT class in each language.  It is so much
clearer and more obvious to _explicitly_ have no value
(Maybe.Nothing()) as opposed to _implicitly_ having no value (null).
Now I find my Java  C++ MaybeT class indispensable when I am
programming in those languages.

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