Re: [Haskell-cafe] A use case for *real* existential types
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
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?
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)
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)
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.
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
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
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
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
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?
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
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...
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
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
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
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
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
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
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
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
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
[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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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