1 Nov 2010 01:31

### Data records. Default values initialisation. Reading datatype from string.

Hello,

I need some help with data records. Normally I can use a read' function to convert string to some data type e.g. (read somestring) :: Type'. However, sometimes I'd like to read a record with some uninitialised fields. I have also set up a default values for my data record, for example: defrec = {a=0,b=1, ..., z=0}'. Now I would like to override some values, so I have a string "defrec{l=100,r=88}", but it seems that it can't be done with read (read "defRec{l=100,r=88}") :: defRec'.

Any suggestions?

Siim
_______________________________________________

1 Nov 2010 01:36

### Re: Data records. Default values initialisation. Reading datatype from string.

Oh sorry, I had some mistakes in my previous mail..
defrec = {a=0,b=1, ..., z=0}' should be defrec = SomeDataConstructor{a=0,b=1, ..., z=0}' .

Siim

On Mon, Nov 1, 2010 at 2:31 AM, Siim Haugas wrote:
Hello,

I need some help with data records. Normally I can use a read' function to convert string to some data type e.g. (read somestring) :: Type'. However, sometimes I'd like to read a record with some uninitialised fields. I have also set up a default values for my data record, for example: defrec = {a=0,b=1, ..., z=0}'. Now I would like to override some values, so I have a string "defrec{l=100,r=88}", but it seems that it can't be done with read (read "defRec{l=100,r=88}") :: defRec'.

Any suggestions?

Siim

_______________________________________________

1 Nov 2010 01:53

### Am I using type families well?

Hello,

I'm trying to make a simple monad (built on operational's ProgramT) for resource loading.
I have classes featuring type families :

{-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs #-}

-- | A ResourceId is something that identifies a resource.
-- It should be unique for one resource, and should be used to find the location (the path) of the resource,
-- possibly by using a configuration datatype
class (Ord id) => ResourceId id where
type LocOf id
type CfgOf id
retrieveLoc :: CfgOf id -> id -> LocOf id

-- | Class describing a resource of type <at> rsc <at>
class (ResourceId (IdOf rsc)) => Resource rsc where
type IdOf rsc
load   :: LocOf (IdOf rsc) -> IO (Maybe rsc)
-- ^ Called when a resource needs to be loaded
unload :: rsc -> IO ()

-- | Then, the operations that the loader can perform
data EDSL id a where
Load     :: id -> EDSL id ()
IsLoaded :: id -> EDSL id Bool
Unload   :: id -> EDSL id ()

type RscLoader rsc m a = ProgramT (EDSL (IdOf rsc)) m a

-- | And finally, how to run a loader
runLoader :: (Monad m, Resource rsc) => CfgOf (IdOf rsc) -> RscLoader rsc m a -> m a
where
eval :: (Monad m, Resource rsc) =>
M.Map (IdOf rsc) rsc
-> ProgramViewT (EDSL rsc) m a
-> m a
eval _    (Return x)     = return x
eval rscs (instr :>>= k) = case instr of
Load id -> do let loc = retrieveLoc cfg id
-- open and load from loc will go here
viewT (k ()) >>= eval rscs
-- -- -- Other cases yet to come...

Well, there is no way I can get it type-check. I think I must be misusing the type families (I tried with multi-param typeclasses and functional dependencies, but it ends up to be the same kind of nightmare...).

_______________________________________________

1 Nov 2010 01:57

### Re: vector-space and standard API for vectors

On 10/31/10 6:36 PM, Alexey Khudyakov wrote:
> On Wed, Oct 27, 2010 at 2:53 AM, wren ng thornton wrote:
>> Is there any good reason for forcing them together? Why not, use the
>> hierarchy I proposed earlier?
>> [...]
>
> 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).

Regardless of the class API instances must obey the law (or else have
buggy results), so the law is uninteresting. We implicitly use such laws
all the time, but usually we do so without having a class constraint to
make our assumptions explicit. Isn't making assumptions explicit part of
the reason for using a strongly typed language?

And as I mentioned previously, the burden of implementation is 2 or 3
*lines* of code. Talking about the number of class instances people must
write is obfuscating the fact that it's trivial to add two lines of
code. And this is code that gets written once, in a library.

> This is tradeoff between usability and generality.

Your proposal, like so many I've seen before, is unusable because it
lacks the necessary generality. The complexity of my proposal is
insignificant: it requires only 2~3 lines of code, and an acknowledgment
that there are structures other than vectorspaces.

> Modules are much less
> frequent and much less known than vector space.

Modules are more frequent than vector spaces, by definition, because
every vector space is a module. Since you're not requiring
Fractional(Scalar v), there isn't even any difference between them in
the class API.

Your claim is like saying that we shouldn't have support for Applicative
because Monads are more common. Again, there are more applicative
functors than monads, the only cognitive overhead of having the
Applicative class is acknowledging that there are structures other than
monads, and adding Applicative enables a helpful style of programming
which there is no reason to exclude.

> 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.

Which my proposal fixes by making associative modules a subclass of both
left- and right-modules.

--

--
Live well,
~wren

1 Nov 2010 02:02

### Re: Reference for technique wanted

On 10/31/10 7:10 PM, Derek Elkins wrote:
> Well, you can get "A Novel Representation of Lists and Its Application
> to the Function 'Reverse'" by John Hughes online published in 1986
> which is referenced by Wadler's 1987 "The Concatenate Vanishes" and
> references Richard Bird's 1984 paper "Transformational programming and
> the paragraph problem" though I'd be quite surprised if that was the
> first place the representation appeared in print.

Barring the "worse than useless" appellation, the technique has been
around in logic programming (and classic Lisp, IIRC) for a few decades
longer. I've always heard it referred to as part of the folklore of
logic/functional programming though, so I'm not sure of any earlier
print references off-hand.

(Though I find it curious that you think the logic version is so
different...)

--

--
Live well,
~wren

1 Nov 2010 03:03

### Re: Reference for technique wanted

On Sun, Oct 31, 2010 at 9:02 PM, wren ng thornton <wren <at> freegeek.org> wrote:
> On 10/31/10 7:10 PM, Derek Elkins wrote:
>>
>> Well, you can get "A Novel Representation of Lists and Its Application
>> to the Function 'Reverse'" by John Hughes online published in 1986
>> which is referenced by Wadler's 1987 "The Concatenate Vanishes" and
>> references Richard Bird's 1984 paper "Transformational programming and
>> the paragraph problem" though I'd be quite surprised if that was the
>> first place the representation appeared in print.
>
> Barring the "worse than useless" appellation, the technique has been around
> in logic programming (and classic Lisp, IIRC) for a few decades longer. I've
> always heard it referred to as part of the folklore of logic/functional
> programming though, so I'm not sure of any earlier print references
> off-hand.

I agree that difference lists have been around quite a bit longer, but
they are something different.

> (Though I find it curious that you think the logic version is so
> different...)

I'm curious as to how you find them similar.  Beyond both of them
being ways to get fast appends in a declarative language, they have no
similarities.  To begin, Prolog is a first order language so it
clearly can't represent functional lists.  Meanwhile, difference lists
rely on, at least, single assignment variables which Haskell does not
have as a language feature so Haskell can't represent difference lists
outside of a monad.  The use of logic variables requires a "linear"
use of a difference list within a branch of non-deterministic
computation, i.e. difference lists are not persistent.  Functional
lists clearly are.  As a simple example, if xs is a functional list, I
can return a pair (xs . ys, xs . zs), if I tried to do that with
difference lists I would be unifying ys and zs.  If I -really- wanted
to do that with difference lists I would have to use a difference list
copy predicate to do it.  Functional lists are an opaque data
structure.  If I want to know what the head of a functional list is, I
have to first turn it into a real list and then take the head.  With
difference lists, I can just look at the head, and this is cheap and
easy.  Both representations have junk, though I'm inclined to say the
functional representation has quite a bit more.  At any rate, the junk
is rather different.  The junk of a the functional representation is
any [a] -> [a] function that can't be put into the form (xs ++) for
some list xs.  For example, reverse.  Difference lists are pairs of
lists where the latter is a suffix of the former.  The junk in the
typical representation, i.e. just pairs of lists, are pairs that don't
meet that criterion.  The idea behind difference lists is to represent
the list xs as the pair (xs ++ ys, ys), i.e. xs ++ ys - ys = xs is
where the name "difference list" comes from.  One way of motivating
the functional representation is that it is nothing more than the
natural embedding of the list monoid into its monoid of endofunctions;
for every set X, X -> X is a monoid, and for every monoid (M,*,1),
curry (*) is a monoid homomorphism from M to (M -> M).  I'm unsure how
to apply either of these views to the other representation.  In fact,
difference lists are nothing more than the normal imperative way of
handling appends quickly for singly-linked lists, with NULL replaced
by an unbound variable.

To simplify, the difference in persistence between the two
representations is enough to consider them very different as it makes
a dramatic difference in interface.

1 Nov 2010 03:26

### Re: Reference for technique wanted


On 1/11/2010, at 2:02 PM, wren ng thornton wrote:
>
> Barring the "worse than useless" appellation, the technique has been around in logic programming (and
classic Lisp, IIRC) for a few decades longer. I've always heard it referred to as part of the folklore of
logic/functional programming though, so I'm not sure of any earlier print references off-hand.
>
> (Though I find it curious that you think the logic version is so different...)

The logic programming version
uses a SINGLE data structure for lists and differences, so that
+ "converting" from the difference representation to the "plain" representation
involves no more than binding a single (logic) variable
+ does not involve ANY overheads compared with building a list directly
+ can easily be traversed while still under construction, as in the
queue([s(...s(z)...), [X1,...,Xn|Hole], Hole)
representation for a queue, which allows O(1) worst case enqueue and dequeue.
enqueue(X, queue(N,List,[X|Hole]),    queue(s(N),List,Hole)).
dequeue(X, queue(s(N),[X|List],Hole), queue(N,List,Hole)).
(Fernando Pereira taught me this one.)
- can only be used once, after which the "hole" has *gone*.

The closure version
uses TWO data structures, so that
- converting from the difference representation to the plain list representation
involves building a whole new data structure at O(n) time and space cost
- requires building closures which have no other reason to exist, which may
retain references to data that would otherwise be dead
- cannot be traversed while under construction
+ can be used as many times as you want

I don't see the "closure" technique used in logic programming at all.

1 Nov 2010 04:14

### Equivalent of withForeignPtr for System.Mem.Weak?

I have an object to which I have added one or more finalizers via
addFinalizer from System.Mem.Weak.  I would like to have a function
that allows me to make use of the object within a block of IO code,
and guarantee that the finalizer(s) will not be called during the code
block -- sort of like withForeignPtr, but for arbitrary objects.  Does
such a function exist, and if not, how could I write one?

I can imagine writing something like:

\begin{code}
withObject :: a -> IO b -> IO b
withObject obj action = do
result <- action
touchObject obj  -- touchObject :: a -> IO ()
return result
\end{code}

However, I don't know how I should implement touchObject and be
confident that it won't ever be optimized out.  Any suggestions?

Cheers,
-Matt

1 Nov 2010 04:34

### Re: Equivalent of withForeignPtr for System.Mem.Weak?

On Sun, Oct 31, 2010 at 10:14 PM, Matthew Steele <mdsteele <at> alum.mit.edu> wrote:
> I have an object to which I have added one or more finalizers via
> addFinalizer from System.Mem.Weak.  I would like to have a function that
> allows me to make use of the object within a block of IO code, and guarantee
> that the finalizer(s) will not be called during the code block -- sort of
> like withForeignPtr, but for arbitrary objects.  Does such a function exist,
> and if not, how could I write one?
>
> I can imagine writing something like:
>
> \begin{code}
> withObject :: a -> IO b -> IO b
> withObject obj action = do
>  result <- action
>  touchObject obj  -- touchObject :: a -> IO ()
>  return result
> \end{code}
>

CC'ing GHC-users list.

The 'primitive' package has a general purpose 'touch' function:

But it doesn't state what guarantees are provided by the function.

Antoine

1 Nov 2010 05:49

### Tsuru Capital Tokyo is looking for Southern Hemisphere summer (Dec 10 - Feb 11) interns

We are looking for an intern that has experience programming in a functional language, and is familiar with Haskell and web development.  Some experience with Linux/Unix system administration is preferred.  Familiarity with Git would be useful.

The position is in Tokyo in a small English speaking team.  We do algorithmic options market-making.

The exact role is not fixed yet but we are looking particularly for someone to help with making a simulation scheduling framework and results visualisation in a web application.

Compensation would be a small package including flights and accommodation.  If interested please send a resume to

jobs <at> tsurucapital.com

You can see more details about the company at

tsurucapital.com  and at the company page on LinkedIn

_______________________________________________