Re: [Haskell-cafe] A use case for *real* existential types

2013-05-10 Thread Andres Löh
Hi.

 So the natural question here is if we can employ the type system to enforce
 this correspondence.   Phantom types immediately come to mind,  as this
 problem is almost the same as ensuring that STRefs are only ever used in a
 single ST computation.   The twist is that the inotify interface has nothing
 analogous to runST,  which does the heavy lifting of the type magic behind
 the ST monad.

 This twist is very simple to deal with if you have real existential types,
 with the relevant part of the interface looking approximately like

 init :: exists a. IO (Inotify a)
 addWatch :: Inotify a - FilePath - IO (Watch a)
 rmWatch :: Inotify a - Watch a - IO ()

You can still do the ST-like encoding (after all, the ST typing trick
is just an encoding of an existential), with init becoming like
runST:

 init :: (forall a. Inotify a - IO b) - IO b
 addWatch :: Inotify a - FilePath - IO (Watch a)
 rmWatch :: Inotify a - Watch a - IO ()

Looking at your inotify.hs, the code of init becomes:

 init :: (forall a. Inotify a - IO b) - IO b
 init k = do
   nextWatchRef_ - newIORef 0
   currentWatchesRef_ - newIORef []
   k $ Inotify {
 nextWatchRef = nextWatchRef_
   , currentWatchesRef = currentWatchesRef_
   }

And the code of main becomes:

 main = init $ \ nd0 - do
   wd0 - addWatch nd0 foo
   wd1 - addWatch nd0 bar
   init $ \ nd1 - do
 wd3 - addWatch nd1 baz
 printInotifyDesc nd0
 printInotifyDesc nd1
 rmWatch nd0 wd0
 rmWatch nd1 wd3
   -- These lines cause type errors:
   --  rmWatch nd1 wd0
   --  rmWatch nd0 wd3
 printInotifyDesc nd0
 printInotifyDesc nd1

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] GSoC - A Cabal Project

2013-04-30 Thread Andres Löh
Hi.

Martin and I have already talked about this project quite a bit. I
think it would be very useful functionality to have, and there's a
good progression from some goals that are relatively easy to reach
with low risk (but already useful) to other goals that are much more
advanced and ambitious that will ensure that there's not going to be a
shortage of work. The project would have the additional benefit of
someone who is not me having to work deep within the modular
dependency solver, which would hopefully result in improved
documentation and possibly some refactorings that make the code easier
to understand.

(And yes, I would be willing to be mentor for this project.)

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] version of containers fixed by template-haskell?

2013-04-17 Thread Andres Löh
 ghc is installed globally, and local packages should not break it.

 still cabal-install says so (and I don't dare to test ...)

If you're installing locally or (even better) in a sandbox, then you
cannot completely (i.e., irrevocably) break your compiler. You can
always remove the package db. Yes, Cabal warns you nevertheless,
because if the user package db is your current context, the ghc
package will subsequently be broken in that context, and that can be
bad/inconvenient enough in practice.

Cheers,
  Andres

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


Re: [Haskell-cafe] Derving NFData via Generics from a type that has a vector doesn't work. (was trying to understand out of memory exceptions)

2013-04-17 Thread Andres Löh
Hi again.

 instance NFData (V.Vector a) where rnf a = force a `seq` ()


 any reason why something like this isn't part of the vector library?

Quoting from the Changelog at http://hackage.haskell.org/package/vector :


Changes in version 0.10

   *  NFData instances


So it's there, and even in the current Haskell Platform.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Derving NFData via Generics from a type that has a vector doesn't work. (was trying to understand out of memory exceptions)

2013-04-16 Thread Andres Löh
Hi Anatoly.

I don't think that the normal deepseq package currently provides
generic deriving at all. This doesn't have anything to do with vector.
There's a default implementation for rnf that defines it to be seq,
which is not what you want in this case, of course. There are
additional packages that implement such functionality, though.

By using deepseq-generics, you can import Control.DeepSeq.Generics and
then define

 instance NFData Simple where rnf = genericRnf

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Haskell is a declarative language? Let's see how easy it is to declare types of things.

2013-04-03 Thread Andres Löh
Hi Johannes.

I know this isn't really an answer, but ...

 1. for explicit declaration of type variables, as in

 reverse :: forall (a :: *) . [a] - [a]

 I have to switch on RankNTypes and/or KindSignatures (ghc suggests).

... you can do this with ExplicitForall rather than RankNTypes,
which indeed does not enable rank-n types, but only allows you to use
the forall syntax.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] generalized, tail-recursive left fold that can finish tne computation prematurely

2013-02-18 Thread Andres Löh
Hi.

 while playing with folds and trying to implement `!!` by folding, I came to
 the conclusion that:

 - `foldr` is unsuitable because it counts the elements from the end, while
 `!!` needs counting from the start (and it's not tail recursive).

What is the problem with the following definition using foldr?

 index :: Int - [a] - a
 index n xs =
   foldr
 (\ x r n - if n == 0 then x else r (n - 1))
 (const (error $ No such index))
 xs
 n

Cheers,
  Andres

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


Re: [Haskell-cafe] Structured Graphs

2013-02-13 Thread Andres Löh
Hi John.

 What are the prospects for Haskell supporting Structured Graphs as defined
 here?
 http://www.cs.utexas.edu/~wcook/Drafts/2012/graphs.pdf

 Is there an interest by developers of GHC in doing this?

Could you be more specific about the kind of support you'd expect
from GHC? Basically all the code in the paper just works with current
GHC, no specific support is needed.

Cheers,
  Andres

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


Re: [Haskell-cafe] Why does not zipWith' exist

2013-02-01 Thread Andres Löh
Hi Kazu.

I'd be surprised if zipWith' yields significant improvements. In the
case of foldl', the strictness affects an internal value (the
accumulator). However, in the case of zipWith', you're just forcing
the result a bit more, but I guess the normal use pattern of fibs is
that you want to see a prefix of the result anyway. So the overall
amount of evaluation is the same.

I've tried to hack up a quick criterion test comparing my own naive
zipWith, the Prelude zipWith (which may have additional optimizations,
I haven't checked), and zipWith':

import Criterion.Main
import Prelude hiding (zipWith)
import qualified Prelude as P

zipWith :: (a - b - c) - [a] - [b] - [c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _  _  = []

zipWith' :: (a - b - c) - [a] - [b] - [c]
zipWith' f (a:as) (b:bs) = x `seq` x : zipWith' f as bs
  where
x = f a b
zipWith' _ _ _ = []

fibs :: () - [Integer]
fibs () = go
  where
go :: [Integer]
go = 0 : 1 : zipWith (+) go (tail go)

fibsP :: () - [Integer]
fibsP () = go
  where
go :: [Integer]
go = 0 : 1 : P.zipWith (+) go (tail go)

fibs' :: () - [Integer]
fibs' () = go
  where
go :: [Integer]
go = 0 : 1 : zipWith' (+) go (tail go)

main :: IO ()
main = defaultMain $ [
bench fibs  (nf (take 1 . fibs ) ())
  , bench fibsP (nf (take 1 . fibsP) ())
  , bench fibs' (nf (take 1 . fibs') ())
  ]

The additional () arguments are to prevent GHC from sharing the list
in between calls. I haven't tested thoroughly if GHC looks through
this hack and optimizes it anyway.

Compiling without optimization, I get 1.15ms/1.11ms/1.10ms.
With -O, I get 85us/85us/88us.

Am I overlooking anything? What's your test?

Cheers,
  Andres

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


Re: [Haskell-cafe] Why does not zipWith' exist

2013-02-01 Thread Andres Löh
 Well, it took a little bit of persuasion to let GHC not cache the list(s), but
 with


 fibs :: Int - Integer
 fibs k = igo i !! k
   where
 i | k  100 = 1
   | otherwise   = 2
 igo :: Integer - [Integer]
 igo i = let go = 0 : i : zipWith (+) go (tail go) in go

 etc., benchmarking

 main :: IO ()
 main = defaultMain $ [
 bench fibs  (whnf fibs 2)
   , bench fibsP (whnf fibsP 2)
   , bench fibs' (whnf fibs' 2)
   ]

 shows a clear difference:

 benchmarking fibs
 mean: 14.50178 ms, lb 14.27410 ms, ub 14.78909 ms, ci 0.950
 benchmarking fibsP
 mean: 13.69060 ms, lb 13.59516 ms, ub 13.81583 ms, ci 0.950
 benchmarking fibs'
 mean: 3.155886 ms, lb 3.137776 ms, ub 3.177367 ms, ci 0.950

Right, I'm not arguing that it's impossible to produce a difference,
but I think that if you're defining the sequence of fibs, the most
likely scenario might be that you're actually interested in a prefix,
and more importantly, you can still, from the outside, force the
prefix even if you're only interested in a particular element. The
second point, imho, is what makes zipWith inherently different from a
function such as foldl'. You can equivalently define zipWith' as a
wrapper around zipWith:

zipWith' :: (a - b - c) - [a] - [b] - [c]
zipWith' f xs ys = strictify (zipWith f xs ys)
  where
strictify :: [a] - [a]
strictify []   = []
strictify (x : xs) = x `seq` x : strictify xs

You cannot easily do the same for foldl and foldl'.

Cheers,
  Andres

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


Re: [Haskell-cafe] why GHC cannot infer type in this case?

2013-01-31 Thread Andres Löh
Hi Dmitry.

 I try to implement little typed DSL with functions, but there is a problem:
 compiler is unable to infer type for my functions. It seems that context
 is clear, but still GHC complains Could not deduce
 It is sad because without type inference the DSL will be very difficult to
 use.

 Could someone explain me why this happens and how it can be avoided?

Pattern matches on GADT generally require type information. Type
inference in such a case is tricky. GADTs are so powerful that in many
cases, there's no unique best type to infer.

As a contrived example, consider this datatype and function:

 data X :: * - * where
C :: Int - X Int
D :: X a

 f (C n) = [n]
 f D = []

What should GHC infer for f? Both

 f :: X a - [Int]
 f :: X a - [a]

are reasonable choices, but without further information about the
context, it's impossible to say which one of the two is better.

It is theoretically possible to be more clever than GHC is and infer
the types of GADT pattern matches in some cases. However, it is (A) a
lot of work to implement and maintain that cleverness, and (B) it is
then very difficult to describe when exactly a type signature is
required and when it isn't. So GHC adopts the simpler approach and
requires type information for all GADT pattern matches, which is a
simple and predictable rule.

How to prevent such errors in general is difficult to say. In your
particular case, there might be an option, though. If you additionally
use TypeFamilies and FlexibleInstances, you can define:

 class MkDecl d where
   type MkDeclSeq d :: TSeq
   type MkDeclRes d :: TypeExp
   decl' :: d - Seq (MkDeclSeq d) - Exp (MkDeclRes d)

 instance MkDecl (Exp r) where
   type MkDeclSeq (Exp r) = TSeqEmpty
   type MkDeclRes (Exp r) = r
   decl' e = \ SeqEmpty - e

 instance MkDecl d = MkDecl (Exp w - d) where
   type MkDeclSeq (Exp w - d) = TSeqCons w (MkDeclSeq d)
   type MkDeclRes (Exp w - d) = MkDeclRes d
   decl' f = \ (SeqCons x xs) - decl' (f x) xs

 decl :: MkDecl d = d - Exp (TFun (MkDeclSeq d) (MkDeclRes d))
 decl d = Decl (decl' d)

 fun = decl $ \ x - Add (Int16 2) x

The idea here is to avoid pattern matching on the GADT, and instead
use an ordinary Haskell function as an argument to the decl smart
constructor. We use the type class and two type families to pack that
function (with as many arguments as it has) into the type-level list
and wrap it all up in the original Decl. This works because on the
outside, no GADT pattern matches are involved, and within the type
class instances, the necessary type information is present.

This is certainly harder to understand than your original version. On
the other hand, it's actually easier to use.

(It's entirely possible that my code can be simplified further. I
haven't thought about this for very long ...)

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Generics pattern matching

2012-12-06 Thread Andres Löh
Hi Joerg.

I must admit that I do not fully understand the big picture, i.e., why
you want to do what you are trying to do. It might be possible to
recommend a better solution using a library such as guarded-rewriting
on Hackage then. I've tried to look up the SO question
(http://stackoverflow.com/questions/13436366/manipulating-arbitrary-tuples),
but it doesn't really make me understand your goal completely either.

In the code you provide, which is taken from one of the answers, the
Bool parameter indeed ensures that the first element of a chain of
products is treated in a different way from the rest. The key to this
behaviour is the line

 rewrite x (a :*: b) = rewrite x a :*: rewrite True b

Here, assuming rewrite is first called with False, we ensure that the
very first component of the nested product will be called with False,
all others with True. Hence all but the first component will end up
being rewritten.

If you'd like to rewrite all but the last, you could achieve this just
by writing

 rewrite x (a :*: b) = rewrite True a :*: rewrite x b

instead. If you want to keep the first and the last component, you
need to propagate more information than a simple Bool. One option is
to create a special-purpose datatype:

 data What = Both | First | Last | None
   deriving Eq

The type of rewrite becomes:

 rewrite :: What - f a - (Rewrite f) a

The idea is that the What argument is initialized to Both, and in
every product case, we split the current value of What to keep track
if we are in the leftmost part of the product (First), the rightmost
part of the product (Last), or elsewhere (None). For this, we define

 splitWhat :: What - (What, What)
 splitWhat Both  = (First, Last)
 splitWhat First = (First, None)
 splitWhat Last  = (None,  Last)
 splitWhat None  = (None,  None)

The product case of rewrite is now:

 rewrite x (a :*: b) = rewrite y a :*: rewrite z b
   where (y, z) = splitWhat x

We also need to slightly modify the K1 case of rewrite. We now want to
perform the rewrite if What is anything but None:

 rewrite w (K1 x) | w /= None, Just val - cast x = K1 val
 rewrite _ _ = K1 NIL

Does this help you?

(I'm attaching the full code.)

Cheers,
  Andres

--
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com


GRewrite.hs
Description: Binary data
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cabal failures...

2012-11-20 Thread Andres Löh
Hi Johan.

I haven't looked in detail at the overall problem, but:

 Flags chosen: base3=True, base4=True

 Why is Cabal setting both base3 and base4 to True?

This looks completely fine to me.

The Cabal .cabal file is stating:

  if flag(base4) { build-depends: base = 4 } else { build-depends: base  4 }
  if flag(base3) { build-depends: base = 3 } else { build-depends: base  3 }

So it's relatively clear to me that both have to be true.

Cheers,
  Andres

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


Re: [Haskell-cafe] non-uniform recursive Trie

2012-10-29 Thread Andres Löh
Hi Kazu.

 I'm now studying Trie in Okasaki's Purely Functional Data Structure.
 Attached is the program in its appendix. I cannot understand how to
 use empty, look and bind. For instance, if I type 'look  empty',
 I got an error:

 look  empty
 interactive:2:1:
 No instance for (FiniteMap m0 [Char])
   arising from a use of `look'
 Possible fix: add an instance declaration for (FiniteMap m0 [Char])
 In the expression: look  empty
 In an equation for `it': it = look  empty

 I have no idea how to determine the parameter 'm'. Suggestions would
 be appreciated.

The code you've listed shows how to go from an already existing
instance of class FiniteMap to an instance for the same class that
adds a trie structure on top of the underlying finite map
implementation. You have to add a base instance to the code so that
it can work. For example, by importing Data.Map and adding an
instance FiniteMap Data.Map.Map Char with the appropriate
definitions.

You'll also need to add extra type information to empty in your
example expression so that GHC can know which instance you actually
want.

Cheers,
  Andres

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


Re: [Haskell-cafe] Type-directed functions with data kinds

2012-10-25 Thread Andres Löh
Hi Iavor.

 If you don't want to use the class system, you could write `repeat` with a
 type like this:

 repeat :: Proxy n - a - Vector n a

 (`Proxy` is the singleton family 'data Proxy n = Proxy`).

How is the polymorphism becoming any less parametric by using this
particular Proxy type?

Cheers,
  Andres

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


Re: [Haskell-cafe] Cabal dependencies

2012-10-06 Thread Andres Löh
 Do you have any suggestions to install xmobar in this particular case?

 In case of executables I usually rm -rf ~/.ghc, cabal install,
 and rm -rf ~/.ghc again. Executables are still here (in ~/.cabal/bin),
 but all libraries are lost. Warning: it may break your development
 environment, so make sure you know what you are doing.

 Better solution could be sandbox tools like cabal-dev. They alloy you to
 setup development environment per project.

In this particular case, removing all libraries is total overkill.
That should be reserved for situations where the package DB is already
broken, but afaiu, this has not happened here yet.

I'm quite convinced xmobar-0.15 actually works with the more recent mtl. So
you can try:

$ cabal unpack xmobar
$ cd xmobar-0.15

edit the xmobar.cabal file and remove the upper bound from mtl

$ cabal install

Cheers,
  Andres

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


Re: [Haskell-cafe] [Haskell] Well-Typed and Skills Matter offer Haskell courses in London in October

2012-09-19 Thread Andres Löh
 Is there an informal hangout without the £225 price-tag

Certainly a great idea. I guess there's most likely some informal
meeting after the Haskell eXchange. Perhaps Neil Mitchell knows if
there are any concrete plans yet? He's been putting together the
program for the conference.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] [Haskell] Well-Typed and Skills Matter offer Haskell courses in London in October

2012-09-19 Thread Andres Löh
Hi.

 Oops, I hit send too prematurely, sorry for the seeming bluntness (but it is
 still a blunt message, can't apologize for that I suppose):

No need to apologize. There's a need for informal meetings as much (or
even more) as there is for courses and conferences.

 Perhaps a monthly informal gathering similarly (self-)organised to Dorkbot
 but focussed on Haskell (and other functional languages) is what I'm really
 after, but that still requires some organisation time and a venue, neither
 of which necessarily come cheap :(

There are several informal meetings on Haskell happening throughout
the world. I'm personally not living in the London area, but I
regularly attend the Munich Haskell meeting
(http://www.haskell-munich.de/). Regarding London, I know there's the
Haskell Hoodlums meetup (http://www.meetup.com/hoodlums/), and I think
there is or was a Haskell User Group as well, but it's currently
listed as not active on
http://www.haskell.org/haskellwiki/User_groups. Perhaps there's a
chance to bring it back to life?

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Detecting numeric overflows

2012-07-31 Thread Andres Löh
Hi.

On Mon, Jul 30, 2012 at 8:47 AM, Евгений Пермяков permea...@gmail.com wrote:
 Can someone tell me if there are any primitives, that used to detect machine
 type overflows, in ghc haskell ? I perfectly understand, that I can build
 something based on preconditioning of variables, but this will kill any
 performance, if needed.

There's

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

It's not implemented quite as efficiently as it theoretically could
be, but it might do more or less what you want.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Fwd: hackage compile failure with QuickCheck 2.5

2012-07-18 Thread Andres Löh
 I'm talking about unattended automated builds, so tweaking isn't an
 option.  On the other hand breaking the package environment isn't so bad,
 because I'm throwing it away after each build.

I'm not convinced that we should try to build packages at any price.
If they're likely to cause problems in a standard environment on a
user machine, then isn't it better to see this reflected on Hackage?

 So in short, no combination of flags will work in this case, I think.
 Failure is the best option.

 Actually --force-reinstalls does work in this case, and this thread began
 with Levent being unhappy with the failure option for his package, so
 I'm tempted to use that flag on all hackage builds.

Does it produce a usable package and environment, or does it just
work, but leave everything broken? I agree that using
--force-reinstalls on Hackage might be an acceptable option, and it's
probably better than using --avoid-reinstalls by default. However, it
may still send the misleading message that a package builds just
fine when it practice it doesn't.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Fwd: hackage compile failure with QuickCheck 2.5

2012-07-17 Thread Andres Löh
Hi.

 QuickCheck's constraint is template-haskell = 2.4, which doesn't explain
 why cabal wanted to install 2.6.0.0 when 2.7.0.0 was already present.

 Also, I'd expect --avoid-reinstalls to stop it reinstalling anything,
 but apparently it doesn't do that with the modular solver.

Assuming the examples you gave are the ones that Hackage actually
uses: Is it necessary that Hackage uses an unreleased and older
version of cabal-install? I can't really tell right now what the
differences between 0.13.3 and 0.14.0 are, but clearly, if the modular
solver isn't the default, then there still are significant
differences. AFAIK --avoid-reinstalls is completely ignored by the old
solver, but *not* by the modular solver.

For me, 2.6.0.0 is picked with --avoid-reinstalls *because* 2.7.0.0 is
already present, and 2.6.0.0 isn't. In concrete terms, with
Cabal-1.14.0, cabal-install-0.14.0 and a ghc-7.4.1-based Haskell
Platform installation without further packages:

$ cabal install --dry-run sbv
Resolving dependencies...
In order, the following would be installed:
containers-0.5.0.0 (new version)
mtl-2.1.2 (new version)
strict-concurrency-0.2.4.1 (new package)
syb-0.3.7 (new version)
template-haskell-2.7.0.0 (reinstall) changes: containers-0.4.2.1 - 0.5.0.0
QuickCheck-2.5 (new version)
sbv-2.2 (new package)
Warning: The following packages are likely to be broken by the reinstalls:
ghc-7.4.1
haddock-2.10.0
QuickCheck-2.4.2
haskell-platform-2012.2.0.0
Use --force-reinstalls if you want to install anyway.

$ cabal install --dry-run sbv --avoid-reinstalls -v
Reading available packages...
Choosing modular solver.
Resolving dependencies...
In order, the following would be installed:
containers-0.5.0.0 (new version)
mtl-2.1.2 (new version)
strict-concurrency-0.2.4.1 (new package)
syb-0.3.7 (new version)
template-haskell-2.6.0.0 (new version)
QuickCheck-2.5 (new version)
sbv-2.2 (new package)

I haven't had time to thoroughly look at this problem, but it
currently seems to me like it's triggered by containers-0.5.0.0 and
has nothing to do with QuickCheck. The containers package is a
dependency of template-haskell. So if containers is upgraded to 0.5,
then template-haskell-2.7.0.0 would have to be reinstalled. With
--avoid-reinstalls, cabal-install will pick an older template-haskell,
not knowing that this will lead to a failure at build time. There's
really no other chance, because sbv-2.2 seems to depend on
containers-0.5.0.0. With containers being a dependency of GHC core
libraries such as template-haskell, there isn't currently a good
option to use containers-0.5.0.0 with ghc-7.4.

Using --avoid-reinstalls blindly or as a default flag is also
unfortunately not a good idea in general. There are simply too many
cases where installing older versions of packages (which is often the
only thing that helps) is not really the solution you want. That's
also the reason why it's not enabled by default.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] sample terms and interpreting program output from Tc Monad

2012-07-09 Thread Andres Löh
[Sorry, I forgot to reply to the list.]

Hi.

 I understand these to be Rank 0 terms:

 (\(x::Int) . x) (0 :: Int) :: (forall. Int) -- value

 (\(x::Int). x) :: (forall. Int - Int)

Yes.

 (\(x::a). x) :: (forall. a - a)

 Although the program prints forall, the absence of a type variable
 indicates Rank 0, correct?

It's a bit unclear what you mean, and the prototype implementation you
seem to be using deviates from Haskell conventions here. The prototype
checker sees a as a type constant here, so it plays the same role as
Int before. In particular, a isn't a type variable, and there's no
quantification.

 I understand these to be Rank 1 terms:

 (\x. x) :: (forall a. a - a) -- This is not the same as the third
 example above, right? This one identifies the type variable a, the one
 above does not. Also, there's no explicit annotation, it's inferred.

The implementation indeed considers them to be different. Before a
was a concrete type, and the function was the monomorphic identity
function on that type. Now, a is a type variable, and the function
is the polymorphic identity function.

[...]

 I understand these to be Rank 2 terms:

 (\(x::(forall a. a)). 0) :: (forall. (forall a. a) - Int)

 The explicit forall annotation on the bound and binding variable x
 causes the program to infer a Rank 2 polytype as indicated by the -
 Int following the (forall a. a), while noting the absence of a type
 variable following the left-most forall printed by the program, correct?

Your description here is a bit strange. It's a rank-2 type because
there's a rank-1 type occurring to the left of the function arrow.


 (\(x::(forall a. a - a)). x) :: (forall b. (forall a. a - a) - b -
 b)

 Also Rank 2, only one arrow to the right of (forall a. a - a) counts.

It's rank 2, yes. I'm not sure what you mean here by saying that only
one arrow counts.

 The universal quantifier on type variable b ranges over the type
 variable a, correct?

No. The universal quantifier ranges over all (mono)types.

 I understand this to be a Rank 3 term:

 (\(f::(forall a. a - a)). \(x::(forall b. b)). f (f x)) :: (forall c.
 (forall a. a - a) - (forall b. b) - c)

No, this is still rank 2. It uses two rank 1 types as function
arguments. For it to be rank 3, it'd have to use a rank 2 type in the
argument position of a function type. Note that the function arrow
associates to the right:

forall c. (forall a. a - a) - ((forall b. b) - c)  -- rank 2
(forall c. ((forall a. a - a) - (forall b. b)) - c) -- rank 3

 The arrows to the right of the universally quantified a and b
 expressions qualify this as Rank 3.

No, you seem to be applying a wrong definition of rank. The correct
definition is given in Section 3.1 of the paper.

Here's how you can derive the type above as a sigma_2:

sigma_2
  ~  forall c. sigma_2
  ~  forall c. sigma_1 - sigma_2
  ~  forall c. sigma_1 - sigma_1 - sigma_2
  ~  forall c. sigma_1 - sigma_1 - sigma_1
  ~  forall c. sigma_1 - sigma_1 - sigma_0
  ~  forall c. sigma_1 - sigma_1 - c
  ~  forall c. (forall a. sigma_1) - sigma_1 - c
  ~  forall c. (forall a. sigma_0) - sigma_1 - c
  ~  forall c. (forall a. tau - tau) - sigma_1 - c
  ~  forall c. (forall a. a - a) - sigma_1 - c
  ~  forall c. (forall a. a - a) - (forall b. sigma_1) - c
  ~  forall c. (forall a. a - a) - (forall b. sigma_0) - c
  ~  forall c. (forall a. a - a) - (forall b. b) - c

 Type variable c ranges over type
 variables a and b, correct?

No. Each of the type variables ranges over all (mono)types. (Or do you
mean what the scope of c is? If so, then the scope of c is the
complete type signature.)

Cheers,
  Andres

--
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] cabal doens't forget old dependencies

2012-06-27 Thread Andres Löh
Hi.

 I tried to install reactive-banana. This failed due to a dependency conflict, 
 and then I noticed there was a newer version of reactive-banana. So I did 
 cabal update, and tried to install again. But whatever I do, cabal keeps 
 trying to install fclabels, but fclabels is no longer a dependency of 
 reactive-banana-0.6.0.0! How can I let cabal forget this dependency?

From the reactive-banana Cabal file:

if flag(UseExtensions)
extensions: TypeFamilies, GADTs, MultiParamTypeClasses,
BangPatterns, TupleSections,
EmptyDataDecls
build-depends:  QuickCheck = 1.2   2.5,
fclabels == 1.1.*,
unordered-containers = 0.2.1.0   0.3,
hashable == 1.1.*
CPP-options:-DUseExtensions

So try -f-UseExtensions if you really want that?

Cheers,
  Andres


-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] cabal doens't forget old dependencies

2012-06-27 Thread Andres Löh
Hi.

On Wed, Jun 27, 2012 at 6:14 PM, Sjoerd Visscher sjo...@w3future.com wrote:
 Ah, ok. I wasn't aware how flags work in Cabal, thanks.

 Makes me wonder why that flag was turned off on hackage.
 http://hackage.haskell.org/package/reactive-banana

I'm not sure it was turned off. I see that it lists only some of the
dependencies. It's a general phenomenon. I don't understand the way
Hackage lists package dependencies. I'd appreciate if it'd actually
show the whole conditional tree of dependencies.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Again, version conflicting problem with cabal-install

2012-06-19 Thread Andres Löh
Hi.

 Hackage A depends on magicloud (any) and container (0.4.0.0), and
 hackage magicloud depends on container (any).
 Now I've installed magicloud, using container 0.5.0.0. Then I failed
 to install A, with any solver.

 So the solvers are using the status that is installed, not the
 definitions from original hackages?

Could you please provide me with something I can reproduce? I'm not
sure what you mean by A or magicloud. Are you saying they have no
further dependencies except for the one on container? If you could
just state which concrete packages have caused the problem, it'd
probably be easier. The trace output of the modular solver with -v3
would also help (send it to me personally if it's too long).

Thanks.

Andres

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


Re: [Haskell-cafe] [Haskell] JustHub 'Sherkin' Release

2012-06-16 Thread Andres Löh
Hi Chris.

[Sorry if I'm slow responding, but I'm at a summer school right now
and have relatively little time to follow my email.]

 At issue is whether the JustHub Haskell distribution for Enterprise Linux
 and
 the hub hackage for sandboxing development projects and integrating multiple
 GHC
 tool chains is redundant because all of the functionality is covered by the
 Nix Haskell distribution, allowing as they do multiple Nix Haskell releases
 to
 be deployed simultaneously.]

Let me clarify this in advance: I'm *not* questioning the usefulness
of JustHub at all! It's great that you provide it. I was asking
whether integrating JustHub *into* Nix and/or NixOS would make sense
and would provide any benefit on top of the features already provided
by these systems. As I indicated, I'm not yet convinced of that. I
asked the question in order to learn more about JustHub. I do
completely understand that Nix is not for everyone and that JustHub
may have less dependencies that make it a very attractive choice for a
wide range of applications.

        All of the standard Haskell tools inter-operate cleanly and
        transparently with the sandboxes and operate in the normal way
outside of them.

I guess this may be the main point. You're saying you can use the
standard tools to work with hubs and don't need to do anything
special, whereas in Nix(OS) you admittedly only get the full benefit
of the system if you're installing packages via Nix rather than via
Cabal.

As Peter has pointed out, you're usually working in Nix(OS) with
several profiles. Each of these profiles can contain an arbitrary set
of packages (not limited to Haskell or GHC). It's possible to switch
between profiles easily. It's possible to use different profiles for
development on different projects. Different profiles can contain
different versions of GHC as well as different sets or variants of
packages.

        Sandboxed environments (hubs) can be shared between work trees as well
        as being (re)named, annotated, replicated, swapped, archived, locked
        and removed. Proper package deletion with the option of garbage
        collecting orphaned code and documentation is also supported.

I'm not completely sure what each of these mean. Package removal is
certainly supported in Nix(OS), but again, admittedly, not via the
standard tools. You have to invoke nix-specific commands in order to
perform garbage collection.

 I have loaded GHC-7.4.1 platform and the GHC-7.0.4 into Nix and it installs
 all of the ghc drivers
 into a single bin directory in the user's profile. I am guessing that
 running `ghc` will generally
 get you the latest compiler you have installed (7.4.1 in my case); specific
 releases can be
 invoked with ghc-7.0.4, etc.

Installing the latest version into the main user profile is merely the
default functionality. There's absolutely no problem selecting older
versions or installing into separate profiles. If you look at the
files actually installed, you'll find that all files in a profile are
just links, and that each Haskell package in fact lives in isolation
in its own directory in the Nix store.

 This hardly covers all of the above functionality!

It might not. We're having this discussion in order to find out, I think :)

 Quite related to this (in my mind anyway) are the user-level facilities for
 managing the package
 databases that each work tree uses -- the problems that cabal-dev was
 created to solve. What I
 have done is to create a system that manages the environment each source
 work tree uses.
 If you are in a 2012.2.0.0-based project work tree then the ghc-driver will
 detect that and invoke
 the right tools. The 2012.2 platform uses cabal-instal-0.14 and that is what
 you will get when
 you invoke cabal in such a work tree.

You still have to say at some initial point what version you want to
use, I hope? Otherwise, I can't see how it could be detected.

 However in work trees based on earlier version of the compiler (e.g.,
 GHC-7.2.2), cabal-install-0.10.2
 will be used because cabal-install-0.14.0 doesn't interoperate very well
 with cabal-0.10 and earlier
 (see https://github.com/haskell/cabal/issues/932). Also in such a work tree
 you will get all
 of the tools that were shipped with the GHC-7.2.2 and all through issuing
 the usual command
 'ghc', 'ghci', 'ghc-pkg', etc).

Independent of concrete bugs, who's making these decisions? Can I use
cabal-install-0.14.0 on projects working with older platforms if I
want to?

 Without some system to help the user invoke the right tools in the right
 context, having to invoke
 each version of the compiler explicitly can get awkward to use quite
 quickly.

This is not required in Nix(OS). You switch the profile and then get
the versions you have in your profile. The profile is not tied to
working dirs, you have to manually switch. I think both approaches
have their disadvantages in practice (i.e., either the user shell or
the working dir are 

Re: [Haskell-cafe] Extending constraints

2012-06-05 Thread Andres Löh
Hi Bas.

I haven't thought about this for long, but ...

 data ProxyWrapper constraint =
    forall a. constraint a = ProxyWrapper (Proxy a)

I'm assuming adding Typable a in ProxyWrapper is not an option for you?

So then what about:

class (c1 a, c2 a) = Ext c1 c2 a
instance (c1 a, c2 a) = Ext c1 c2 a

typeOfInnerProxy :: ProxyWrapper (Ext Typeable constraint) - TypeRep
typeOfInnerProxy (ProxyWrapper p) = typeOfArg p

This will certainly require all sorts of undecidable instances :) But
does it work for you?

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Extending constraints

2012-06-05 Thread Andres Löh
What you want seems a bit tricky.

 p :: ProxyWrapper Num
 p = ProxyWrapper (Proxy :: Proxy Int)

At this point, all you know about p is that it is a Num. You don't
know that it is Typeable, because you choose to forget about that. You
could give p the type 'ProxyWrapper (Ext Typeable Num)' and it would
work.

 then the following would give a type error:

 oops :: TypeRep
 oops = typeOfInnerProxy p

Yes, and correctly so. Because Typeable isn't even a superclass of
Num. So there's no way to know that p actually contains a Typeable
proxy.

Cheers,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] HPC question

2012-05-23 Thread Andres Löh
Hi David.

 Now, if I fiddle in the .tix file by hand to fake a usage of (/=) by
 changing the 52nd entry from 0 to 1, the Eq instance isn't highlighted any
 more in the HTML output. More strangely, if I then remove the usage of (==)
 by changing the 51st entry from 1 to 0, the Eq instance still isn't
 highlighted. A similar effect happens with the Show instance. It seems to be
 highlighting based only on the last entry in the .tix file, where there are
 two or more identically-placed boxes. Is this right? I'd have expected that
 if I use (==) then the deriving (Eq) clause should be considered 'used'.

I've not looked at the .tix file, but a few tests seem to confirm what
I'd suspect. For derived instances, you have to cover *all* methods,
otherwise the type class will be shown as not covered. Now, in the
case of Eq that's both (==) and (/=), where the derived implementation
of (/=) happens to use the derived implementation of (==). So using
(==) alone is not sufficient, but using (/=) is. Similarly for Show,
where the class defines showList that you don't test.

 Secondly, I can't work out what the four boxes in position 15:6-15:9 are
 supposed to be. If I use -ddump-simpl I can see many calls to 'tick' but
 there's no mention of numbers 47, 49 or 50. Perhaps they've been simplified
 away? I'm afraid I don't know what else to try dumping to get at the
 instrumented code before the simplifier's had a go at it.

For the datatype, your use of field labels causes GHC to generate
accessor functions. These aren't covered by your tests. Therefore the
datatype shows as not completely covered.

HTH,
  Andres

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] library conflicts and how to resolve them

2012-05-06 Thread Andres Löh
Hi.

 $ cabal install persistent
 Resolving dependencies...
 In order, the following would be installed:
 aeson-0.6.0.2 (reinstall) changes: mtl-2.1.1 - 2.0.1.0
 persistent-0.9.0.3 (new package)
 cabal: The following packages are likely to be broken by the reinstalls:
 buildwrapper-0.5.2
 Use --force-reinstalls if you want to install anyway.

 Any ideas what is going on ? I believe aeson-0.6.0.2  is already installed.

Yes.

 And as far as I can tell the build of aeson-0.6.0.2 doesn't require that
 specific version of mtl.

It doesn't, otherwise it couldn't already be installed. Something
persistent depends on in the selected plan depends on mtl-2.0.1.0, and
therefore implies the reinstall.

It'd be interesting to see the trace of the solver (pass -v3 to the
cabal command). You could also try what adding --constraint=mtl ==
2.1.1 yields.

Cheers,
  Andres

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


Re: [Haskell-cafe] ANN: generic-deepseq 1.0.0.0

2012-02-25 Thread Andres Löh
 Would you have an example of a type for which it would be useful to have
 a DeepSeq instance, and that would require a V1 instance? I cannot think
 of one now; I originaly thought it would be necessary to permit deriving
 DeepSeq instances for types tagged with void types, but as José
 explained, in that case, the V1 instance isn't needed because those void
 types don't show up in the representation.

While void datatypes are rare, it just doesn't make sense to exclude
them. It's an arbitrary restriction. Here's a constructed example:

data X a = C1 Int | C2 a
data Z -- empty

type Example = X Z

We're using Z as a parameter to X in order to exclude the use of the
C2 case. Without a V1 case, you cannot use deepSeq on values of type
Example.

Cheers,
  Andres

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


Re: [Haskell-cafe] ANN: generic-deepseq 1.0.0.0

2012-02-24 Thread Andres Löh
I don't understand what's going on here. Instances for V1 should of
course be defined if they can be! And in this case, a V1 instance
makes sense and should be defined. The definition itself doesn't
matter, as it'll never be executed.

Cheers,
  Andres

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


Re: [Haskell-cafe] ANN: generic-deepseq 1.0.0.0

2012-02-24 Thread Andres Löh
Hi.

 I don't understand what's going on here. Instances for V1 should of
 course be defined if they can be! And in this case, a V1 instance
 makes sense and should be defined. The definition itself doesn't
 matter, as it'll never be executed.


 The definition certainly matters:

[...]

You're right. I was too quick to conclude the definition doesn't
matter. But it should still be there. V1 can occur in representations
of non-empty types (even if the current mechanism might not generate
them). You'd still want to be able to call generic functions on such
types.

Cheers,
  Andres

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


Re: [Haskell-cafe] Again, version conflicting problem with cabal-install

2012-02-03 Thread Andres Löh
Hi.

On Fri, Feb 3, 2012 at 7:44 AM, Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com wrote:
 On 3 February 2012 17:29, Magicloud Magiclouds
 magicloud.magiclo...@gmail.com wrote:
 Thank you. The document does say it more clearly than me.
 But still, currently, ghc only gives me one option: cannot be built.
 How about giving me another one: throw away the version information of
 D when building A. So when A uses types in D with B and C, it might
 work. Just the risk is on me now.
 It is not perfect, but would work sometimes

 But not always.  We'd then have other errors: why isn't this build working?

 Types can be re-exported, class instances are implicitly imported/exported, 
 etc.

It's a valid complaint, and there's ongoing work to fix some of these
issues. In the meantime, the development version of cabal-install, in
particular the new modular solver, can deal with a few situations that
can't be resolved by older cabal-install versions. I can't promise it
will help here. But I'm still interested in feedback.

Cheers,
  Andres

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


Re: [Haskell-cafe] Again, version conflicting problem with cabal-install

2012-02-03 Thread Andres Löh
 I am just wanting an option (ignore versions) to take that risk in
 develop environment.

A controlled way of ignoring version constraints (mainly upper bounds,
actually) is certainly on my TODO list for the new solver. The main
issue to work out is a good way how to control the disabled bounds via
the command line, because you usually don't want to ignore all of
them. Currently, my UI-preference is a flag

  --force-allow=foo-1.3

with the semantics that all dependencies on foo will be changed to
allow foo-1.3 to be chosen. Would that be ok? Other suggestions?

Cheers,
  Andres

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


Re: [Haskell-cafe] Again, version conflicting problem with cabal-install

2012-02-03 Thread Andres Löh
Hi.

  --force-allow=foo-1.3

 with the semantics that all dependencies on foo will be changed to
 allow foo-1.3 to be chosen. Would that be ok? Other suggestions?

 Can't this be integrated with the current --constraint flag?

It could be, but ...

 If the
 constraint is able to be satisfied without unrestricting any bounds,
 fine.  Otherwise, unrestrict any bounds on that constraint.  What
 would be the drawbacks?

... it shouldn't happen automatically. There are perfectly valid and
safe reasons to use --constraint, whereas this new feature is
inherently unsafe. But allowing general constraint syntax and calling
the flag something with constraint in it is perhaps a good idea.

 An advantage is being able to specify --constraint='foo = 1.3' to get
 foo-1.3.7.2 instead of having to find out exactly which version you
 want.  And if you already know what you want, you may always say
 --constraint='foo == 1.3.7.2'.

Yes.

 Looking forward to the new solver! =)

I need testers and feedback. You can already use it. It's in the
cabal-install development version, and can be enabled by saying
--solver=modular on the command line.

Cheers,
  Andres

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


[Haskell-cafe] Well-Typed are hiring: Haskell consultant

2012-01-12 Thread Andres Löh
In order to keep up with customer demand, we are looking to hire a
Haskell expert to work with us at Well-Typed
(http://www.well-typed.com/) as a Haskell consultant.

This is an exciting opportunity for someone who is passionate about
Haskell and who is keen to improve and promote Haskell in a
professional context.

The role is quite general and could cover any of the projects and
activities that we are involved in as a company. The tasks may
involve:

* working on the Haskell compilers, libraries and tools;
* Haskell application development;
* working directly with clients to solve their problems.

Well-Typed has a variety of clients. For some we do proprietary
Haskell development and consulting. For others, much of the work
involves open-source development and cooperating with the rest of the
Haskell community: the commercial, open-source and academic users.

At the moment, we are running the Parallel GHC Project
(http://www.haskell.org/haskellwiki/Parallel_GHC_Project/). It is
likely that initial tasks will have some connection with parallel
and/or concurrent programming in Haskell. We are also doing quite a
bit of GHC maintenance, and some knowledge or interest in compiler
internals, operating systems, the foreign language interface, and/or
deployment issues would be welcome.

Our ideal candidate has excellent knowledge of Haskell, whether from
industry, academia, or personal interest. Familiarity with other
languages, low-level programming, and good software engineering
practices are also useful.  Good organisation and ablity to manage
your own time, and reliably meet deadlines, is important. You are
likely to have a batchelor's degree or higher in computer science or a
related field, although this isn't a requirement. Experience of
consulting, or running a business, is also a bonus.

The position is initially as a contractor for one year with a salary
of 150 GBP per day. We offer flexible hours and work from home. Living
in England is not required.

In the longer term there is the opportunity to become a member of the
partnership with a full stake in the business: being involved in
business decisions, and fully sharing the risks and rewards.

If you are interested, please apply via i...@well-typed.com. Tell us
why you are interested and why you would be a good fit for the job,
and attach your CV. Please also indicate when you might be able to
start. We are more than happy to answer informal enquiries. Contact
Duncan Coutts, Ian Lynagh or Andres Löh
(http://www.well-typed.com/who_we_are/) for further information,
either by email or IRC.

The deadline for applications is Friday 27th January 2012.

== About Well-Typed

Well-Typed LLP is a Haskell services company, providing consultancy
services, writing bespoke applications, and offering commercial
training in Haskell and related topics.

-- 
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com

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


Re: [Haskell-cafe] Lifted Spine View

2011-11-21 Thread Andres Löh
Hi there.

    I tried to follow the program of the paper Scrap your boilerpolate
 Revolutions. Unfortunately,
 I found the program in the section lifted spine view does not compile in my
 GHC, could anybody
  point out where I am wrong? Many Thanks

 My code is posted here http://hpaste.org/54357

You have to flip the two fields of (:-), i.e., the type has to be
first and the annotated term has to be second. This is because pattern
matching on GADTs and refinement is implicitly left-to-right in GHC.
The paper presents it the other way round and remarks on the flipped
order in a footnote near the beginning.

Cheers,
  Andres

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


Re: [Haskell-cafe] ghc 7.2.1 Generics problem

2011-11-01 Thread Andres Löh
Hi.

  I do not know why, my ghc 7.2.1 does not seem to support
 DeriveRepresentable. I compiled the ghc 7.2.1 myself by ghc 7.0.4. All
 options default.

 $ ghc Types/TopTalkerRecord.hs

 Types/TopTalkerRecord.hs:2:14:
    Unsupported extension: DeriveRepresentable

There's no extension of that name in 7.2.1. Do you mean DeriveGeneric?

Cheers,
  Andres

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