Re: [Haskell-cafe] plugins fails on a simple example
Any ideas what could be causing the problem? I could try creating a patch, but I have no clue where to start. Best regards, Petr Dne 09/16/2013 11:12 PM, Jeremy Shaw napsal(a): plugins probably needs to be patched[1]. I'll happily apply such a patch. - jeremy [1] or rewritten from the ground up On Mon, Sep 16, 2013 at 2:49 AM, Petr Pudlák petr@gmail.com mailto:petr@gmail.com wrote: Hi, I'm playing with “plugins”, trying to evaluate a simple expression: |import Control.Monad import System.Eval.Haskell main =do let fExpr =1 + 2 :: Int r - eval_ fExpr [Prelude] [] [] [] ::IO (Either [String] (Maybe Int)) case rof Right (Just f) -do print $ f Left err - putStrLn $Error: ++ unlines err _ - putStrLn $Unknown error.| However, it fails with |Error: on the commandline: Warning: -fglasgow-exts is deprecated: Use individual extensions instead| Am I doing something wrong? How can I turn off the flag? I'm using GHC 7.6.3. Thanks, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] plugins fails on a simple example
Hi, I'm playing with plugins, trying to evaluate a simple expression: |import Control.Monad import System.Eval.Haskell main =do let fExpr =1 + 2 :: Int r - eval_ fExpr [Prelude] [] [] [] ::IO (Either [String] (Maybe Int)) case rof Right (Just f) -do print $ f Left err - putStrLn $Error: ++ unlines err _ - putStrLn $Unknown error.| However, it fails with |Error: on the commandline: Warning: -fglasgow-exts is deprecated: Use individual extensions instead| Am I doing something wrong? How can I turn off the flag? I'm using GHC 7.6.3. Thanks, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] a little parsec enhancement
I'd appreciate exporting adding such aliases for creating and running ParsecT the 3.1.x way. Thanks, Petr Dne 09/06/2013 10:56 PM, Antoine Latter napsal(a): The exported `mkPT` is equivalent to the old 'ParsecT' data constructor from parsec 3.0.x. I wouldn't mind exporting a similar alias for the new 'ParsecT' constructor from 3.1.x. On Fri, Sep 6, 2013 at 2:21 PM, Petr Pudlák petr@gmail.com mailto:petr@gmail.com wrote: Dne 09/05/2013 01:38 PM, Roman Cheplyaka napsal(a): * Petr Pudlák petr@gmail.com mailto:petr@gmail.com [2013-09-05 11:18:25+0200] Unfortunately |ParsecT| constructor isn't exported so I'm not able to implement it outside /parsec/. No, but there's an 'mkPT' function which is equivalent to the ParsecT constructor. (Although I, too, wish the ParsecT constructor were exposed.) Roman Yes, I tried to use `mkPT`, but the result looked very complicated and I wasn't quite sure if it'll be working correctly in all cases. Implementing the same thing with the `ParsecT` constructor is simple and comprehensible. Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] a little parsec enhancement
Dne 09/05/2013 01:38 PM, Roman Cheplyaka napsal(a): * Petr Pudlák petr@gmail.com [2013-09-05 11:18:25+0200] Unfortunately |ParsecT| constructor isn't exported so I'm not able to implement it outside /parsec/. No, but there's an 'mkPT' function which is equivalent to the ParsecT constructor. (Although I, too, wish the ParsecT constructor were exposed.) Roman Yes, I tried to use `mkPT`, but the result looked very complicated and I wasn't quite sure if it'll be working correctly in all cases. Implementing the same thing with the `ParsecT` constructor is simple and comprehensible. Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] a little parsec enhancement
Hi, when thinking about this SO question http://stackoverflow.com/q/18583416/1333025, I couldn't find a combinator that allows a parser to /optionally/ fail without consuming input, or consume input and return its value. So I'm suggesting such a function: |-- | @emptyIf p@ parses @p@ and if its return value is @Nothing@, pretends -- that an error has occured with no input consumed. -- -- If @p@ fails and consumes some input, so does @emptyIf p@. Combine with -- 'try' if this is undesirable. emptyIf :: (Stream s m t) =ParsecT s u m (Maybe a) -ParsecT s u m a emptyIf p =ParsecT $ \s cok cerr eok eerr - let cok' (Just x) s e = cok x s e cok'Nothing _ e = eerr e eok' (Just x) s e = eok x s e eok'Nothing _ e = eerr e in unParser p s cok' cerr eok' eerr| With this function, the answer to the SO question becomes really easy: |rcomb :: (Stream s m t) =ParsecT s u m a -ParsecT s u m b -ParsecT s u m b rcomb p q = emptyIf $ runMaybeT (opt p * opt q) where opt =MaybeT . optional-- optional from Control.Applicative!| Whenever |p| or |q| fails without consuming input, then |rcomb p q| fails without consuming input. Unfortunately |ParsecT| constructor isn't exported so I'm not able to implement it outside /parsec/. (Perhaps it would make sense to export |ParsecT| in some module such as |Text.Parsec.Internal|?) Therefore I'm suggesting to add such a function to /parsec/ (darcs patch included). Perhaps change the name, I couldn't think of anything better. Best regards, Petr 1 patch for repository http://code.haskell.org/parsec3: Thu Sep 5 11:12:47 CEST 2013 Petr Pudlak p...@pudlak.name * Add 'emptyIf' which allows a parser to optinally fail without consuming any input. New patches: [Add 'emptyIf' which allows a parser to optinally fail without consuming any input. Petr Pudlak p...@pudlak.name**20130905091247 Ignore-this: 59b93c660fe860acd9a5fff887f7678f ] { hunk ./Text/Parsec/Prim.hs 38 , parserPlus , (?) , (|) +, emptyIf , label , labels , lookAhead hunk ./Text/Parsec/Prim.hs 455 p' = ParsecT $ \s cok cerr eok eerr - unParser p s eok cerr eok eerr +-- | @emptyIf p@ parses @p@ and if its return value is @Nothing@, pretends +-- that an error has occured with no input consumed. +-- +-- If @p@ fails and consumes some input, so does @emptyIf p@. Combine with +-- 'try' if this is undesirable. + +emptyIf :: (Stream s m t) = ParsecT s u m (Maybe a) - ParsecT s u m a +emptyIf p = ParsecT $ \s cok cerr eok eerr - +let cok' (Just x) s e = cok x s e +cok' Nothing _ e = eerr e +eok' (Just x) s e = eok x s e +eok' Nothing _ e = eerr e +in unParser p s cok' cerr eok' eerr + + -- | The parser @token showTok posFromTok testTok@ accepts a token @t@ -- with result @x@ when the function @testTok t@ returns @'Just' x@. The -- source position of the @t@ should be returned by @posFromTok t@ and } Context: [Fix haddock module links. Bjorn Buckwalter bj...@buckwalter.se**20130821095713 Ignore-this: 304217ec8b73f59edcd96dd13aca67af ] [TAG 3.1.3 Antoine Latter aslat...@gmail.com**20120612020909 Ignore-this: 7100375a3e4853c09f1ea993ae32eed7 ] Patch bundle hash: 173111b8bbc5a6eb69d41926053184c35ae9b3cc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Performance of delete-and-return-last-element
Dne 09/01/2013 09:13 PM, Harald Bögeholz napsal(a): Am 31.08.13 14:35, schrieb Petr Pudlák: One solution would be to fold over a specific semigroup instead of a recursive function: |import Data.Semigroup import Data.Foldable(foldMap) import Data.Maybe(maybeToList) data Darle a =Darle {getInit :: [a],getLast ::a } deriving Show instance Semigroup (Darle a)where ~(Darle xs1 l1) ~(Darle xs2 l2) =Darle (xs1 ++ [l1] ++ xs2) l2 darle :: [a] -Darle a darle = foldr1 () . map (Darle [])| It's somewhat more verbose, but the core idea is clearly expressed in the one line that defines ||, and IMHO it better shows /what/ are we doing rather than /how/. It's sufficiently lazy so that you can do something like |head . getInit $ darle [1..]|. I am wondering why you put the Semigroup instance there and what the other imports are for. Doesn't this work just as well? Sorry, the two other imports are redundant, I forgot to erase them when playing with various ideas. The Semigroup instance of course isn't necessary for this particular purpose. But having it (1) signals that the operation satisfies some laws (associativity) and (2) allows the structure to be reused anywhere where a Semigroup is required. For example, we can wrap it into `Option` to get a monoid, and perhaps use it in `foldMap`. This way we extend the functionality to empty collections: ```haskell darle :: Foldable f = f a - Maybe (Darle a) darle = getOption . foldMap (Option . Just . Darle []) ``` Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Performance of delete-and-return-last-element
One solution would be to fold over a specific semigroup instead of a recursive function: |import Data.Semigroup import Data.Foldable(foldMap) import Data.Maybe(maybeToList) data Darle a =Darle {getInit :: [a],getLast ::a } deriving Show instance Semigroup (Darle a)where ~(Darle xs1 l1) ~(Darle xs2 l2) =Darle (xs1 ++ [l1] ++ xs2) l2 darle :: [a] -Darle a darle = foldr1 () . map (Darle [])| It's somewhat more verbose, but the core idea is clearly expressed in the one line that defines ||, and IMHO it better shows /what/ are we doing rather than /how/. It's sufficiently lazy so that you can do something like |head . getInit $ darle [1..]|. Best regards, Petr Dne 08/30/2013 08:18 PM, Lucas Paul napsal(a): Suppose I need to get an element from a data structure, and also modify the data structure. For example, I might need to get and delete the last element of a list: darle xs = ((last xs), (rmlast xs)) where rmlast [_] = [] rmlast (y:ys) = y:(rmlast ys) There are probably other and better ways to write rmlast, but I want to focus on the fact that darle here, for lack of a better name off the top of my head, appears to traverse the list twice. Once to get the element, and once to remove it to produce a new list. This seems bad. Especially for large data structures, I don't want to be traversing twice to do what ought to be one operation. To fix it, I might be tempted to write something like: darle' [a] = (a, []) darle' (x:xs) = let (a, ys) = darle' xs in (a, (x:ys)) But this version has lost its elegance. It was also kind of harder to come up with, and for more complex data structures (like the binary search tree) the simpler expression is really desirable. Can a really smart compiler transform/optimize the first definition into something that traverses the data structure only once? Can GHC? - Lucas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] monoids induced by Applicative/Alternative/Monad/MonadPlus?
Or, if there are no such definitions, where would be a good place to add them? Petr Dne 08/20/2013 06:55 PM, Petr Pudlák napsal(a): Dear Haskellers, are these monoids defined somewhere? |import Control.Applicative import Data.Monoid newtype AppMonoid m a =AppMonoid (m a) instance (Monoid a,Applicative m) =Monoid (AppMonoid m a)where mempty =AppMonoid $ pure mempty mappend (AppMonoid x) (AppMonoid y) =AppMonoid $ mappend $ x * y -- With the () monoid for `a` this becames the monoid of effects. newtype AltMonoid m a =AltMonoid (m a) instance Alternative m =Monoid (AltMonoid m a)where mempty =AltMonoid empty mappend (AltMonoid x) (AltMonoid y) =AltMonoid $ x | y| (and similarly for Monad/MonadPlus, until they become subclasses of Applicative?) Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] monoids induced by Applicative/Alternative/Monad/MonadPlus?
Dear Haskellers, are these monoids defined somewhere? import Control.Applicativeimport Data.Monoid newtype AppMonoid m a = AppMonoid (m a)instance (Monoid a, Applicative m) = Monoid (AppMonoid m a) where mempty = AppMonoid $ pure mempty mappend (AppMonoid x) (AppMonoid y) = AppMonoid $ mappend $ x * y-- With the () monoid for `a` this becames the monoid of effects. newtype AltMonoid m a = AltMonoid (m a)instance Alternative m = Monoid (AltMonoid m a) where mempty = AltMonoid empty mappend (AltMonoid x) (AltMonoid y) = AltMonoid $ x | y (and similarly for Monad/MonadPlus, until they become subclasses of Applicative?) Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] using network+conduit+tls for a client application?
Dear Haskellers, I wanted to write a small TLS application (connecting to IMAP over TLS) and it seemed natural to use conduit for that. I found the network-conduit-tls package, but then I realized it's meant only for server applications. Is there something similar for client applications? Thank you, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Why isn't ArrowChoice a parent of of ArrowApply?
In Control.Arrow we have: |leftApp ::ArrowApply a = a b c - a (Either b d) (Either c d)| Any instance of |ArrowApply| can be made into an instance of |ArrowChoice| by defining |left = leftApp|. So why isn't |ArrowChoice| a parent of |ArrowApply|? Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] mapFst and mapSnd
Dne 28.5.2013 10:54, Dominique Devriese napsal(a): Hi all, I often find myself needing the following definitions: mapPair :: (a - b) - (c - d) - (a,c) - (b,d) mapPair f g (x,y) = (f x, g y) mapFst :: (a - b) - (a,c) - (b,c) mapFst f = mapPair f id mapSnd :: (b - c) - (a,b) - (a,c) mapSnd = mapPair id But they seem missing from the prelude and Hoogle or Hayoo only turn up versions of them in packages like scion or fgl. Has anyone else felt the need for these functions? Am I missing some generalisation of them perhaps? Apart from Arrows, there is also package bifunctors that defines this functionality for (,), Either and a few others: http://hackage.haskell.org/packages/archive/bifunctors/3.2.0.1/doc/html/Data-Bifunctor.html Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Generalizing unionWithKey, unionWith, ...
Dne 28.5.2013 12:32, Johannes Waldmann napsal(a): Jose A. Lopes jose.lopes at ist.utl.pt writes: unionWith :: Ord k = (a - b - c) - Map k a - Map k b - Map k c what should be the result of unionWith undefined (M.singleton False 42) (M.singleton True bar) ? Perhaps the generalized signature should be instead: ```haskell unionWith :: Ord k = (Maybe a - Maybe b - c) - Map k a - Map k b - Map k c ``` (The function would always get at least one `Just`.) But this functionality can be achieved using `map`s and the current `unionWith`. P.P. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Set monad
On 04/12/2013 12:49 PM, o...@okmij.org wrote: One problem with such monad implementations is efficiency. Let's define step :: (MonadPlus m) = Int - m Int step i = choose [i, i + 1] -- repeated application of step on 0: stepN :: (Monad m) = Int - m (S.Set Int) stepN = runSet . f where f 0 = return 0 f n = f (n-1)= step Then `stepN`'s time complexity is exponential in its argument. This is because `ContT` reorders the chain of computations to right-associative, which is correct, but changes the time complexity in this unfortunate way. If we used Set directly, constructing a left-associative chain, it produces the result immediately: The example is excellent. And yet, the efficient genuine Set monad is possible. BTW, a simpler example to see the problem with the original CPS monad is to repeat choose [1,1] choose [1,1]choose [1,1] return 1 and observe exponential behavior. But your example is much more subtle. Enclosed is the efficient genuine Set monad. I wrote it in direct style (it seems to be faster, anyway). The key is to use the optimized choose function when we can. {-# LANGUAGE GADTs, TypeSynonymInstances, FlexibleInstances #-} module SetMonadOpt where import qualified Data.Set as S import Control.Monad data SetMonad a where SMOrd :: Ord a = S.Set a - SetMonad a SMAny :: [a] - SetMonad a instance Monad SetMonad where return x = SMAny [x] m= f = collect . map f $ toList m toList :: SetMonad a - [a] toList (SMOrd x) = S.toList x toList (SMAny x) = x collect :: [SetMonad a] - SetMonad a collect [] = SMAny [] collect [x] = x collect ((SMOrd x):t) = case collect t of SMOrd y - SMOrd (S.union x y) SMAny y - SMOrd (S.union x (S.fromList y)) collect ((SMAny x):t) = case collect t of SMOrd y - SMOrd (S.union y (S.fromList x)) SMAny y - SMAny (x ++ y) runSet :: Ord a = SetMonad a - S.Set a runSet (SMOrd x) = x runSet (SMAny x) = S.fromList x instance MonadPlus SetMonad where mzero = SMAny [] mplus (SMAny x) (SMAny y) = SMAny (x ++ y) mplus (SMAny x) (SMOrd y) = SMOrd (S.union y (S.fromList x)) mplus (SMOrd x) (SMAny y) = SMOrd (S.union x (S.fromList y)) mplus (SMOrd x) (SMOrd y) = SMOrd (S.union x y) choose :: MonadPlus m = [a] - m a choose = msum . map return test1 = runSet (do n1- choose [1..5] n2- choose [1..5] let n = n1 + n2 guard $ n 7 return n) -- fromList [2,3,4,5,6] -- Values to choose from might be higher-order or actions test1' = runSet (do n1- choose . map return $ [1..5] n2- choose . map return $ [1..5] n- liftM2 (+) n1 n2 guard $ n 7 return n) -- fromList [2,3,4,5,6] test2 = runSet (do i- choose [1..10] j- choose [1..10] k- choose [1..10] guard $ i*i + j*j == k * k return (i,j,k)) -- fromList [(3,4,5),(4,3,5),(6,8,10),(8,6,10)] test3 = runSet (do i- choose [1..10] j- choose [1..10] k- choose [1..10] guard $ i*i + j*j == k * k return k) -- fromList [5,10] -- Test by Petr Pudlak -- First, general, unoptimal case step :: (MonadPlus m) = Int - m Int step i = choose [i, i + 1] -- repeated application of step on 0: stepN :: Int - S.Set Int stepN = runSet . f where f 0 = return 0 f n = f (n-1)= step -- it works, but clearly exponential {- *SetMonad stepN 14 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14] (0.09 secs, 31465384 bytes) *SetMonad stepN 15 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] (0.18 secs, 62421208 bytes) *SetMonad stepN 16 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] (0.35 secs, 124876704 bytes) -} -- And now the optimization chooseOrd :: Ord a = [a] - SetMonad a chooseOrd x = SMOrd (S.fromList x) stepOpt :: Int - SetMonad Int stepOpt i = chooseOrd [i, i + 1] -- repeated application of step on 0: stepNOpt :: Int - S.Set Int stepNOpt = runSet . f where f 0 = return 0 f n = f (n-1)= stepOpt {- stepNOpt 14 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14] (0.00 secs, 515792 bytes) stepNOpt 15 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] (0.00 secs, 515680 bytes) stepNOpt 16 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] (0.00 secs, 515656 bytes) stepNOpt 30 fromList [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] (0.00 secs, 1068856 bytes) -} Oleg, thanks a lot for this example, and sorry for my late reply. I really like the idea and I'm hoping to a similar concept soon for a monad representing probability computations. With best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Hackage checking maintainership of packages
Some further ideas: - Make the periodic maintainership reminders optional. Every developer would be able to choose if (s)he wishes to receive them or not. I believe many would choose to receive them. - Maintain the last date the maintainership has been verified - either by an upload of a new version or by explicitly by the author (like by answering a reminder). This way, visitors would have a clear indication what could they expect, regardless of the reminders. - Add some estimate based on the packages that depend on this one. For example, take the maximum of these dates for all packages depending on this one maintained by the same author. It's very likely that if the same person actively develops something that is based on a package, (s)he will care about the package too, even if it hasn't been updated for a while. This would solve perfect stable packages like deepseq. - Alternatively, reminders could be human-triggered, instead of being sent automatically. If the date is older than some bound (like those 3 months), there could be a button like query maintainership. If a visitor presses it, Hackage would send the reminder to the author (if it hasn't sent one recently, of course). This way, the reminder would be sent only for packages that somebody is actually interested in. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Hackage checking maintainership of packages
2013/5/6 Tillmann Rendel ren...@informatik.uni-marburg.de Petr Pudlák wrote: -- Forwarded message -- From: *Niklas Hambüchen* m...@nh2.me mailto:m...@nh2.me Date: 2013/5/4 ... I would even be happy with newhackage sending every package maintainer a quarterly question Would you still call your project X 'maintained'? for each package they maintain; Hackage could really give us better indications concerning this. This sounds to me like a very good idea. It could be as simple as If you consider yourself to be the maintainer of package X please just hit reply and send. If Hackage doesn't get an answer, it'd just would display some red text like This package seems to be unmaintained since D.M.Y. I like the idea of displaying additional info about the status of package development, but I don't like the idea of annoying hard-working package maintainers with emails about their perfect packages that actually didn't need any updates since ages ago. I understand, but replying to an email with an empty body or clicking on a link once in a few months doesn't seem to be an issue for me. And if somebody is very busy and doesn't update the package, it's more fair to signal from the start that (s)he doesn't want to maintain the package. Personally it happened to me perhaps several times that I used a promising package and discovered later that's it's not being maintained. I'd say that the amount of time required to confirm if authors maintain their packages is negligible compared to the amount of time people lose this way. Just out of curiosity, do you have some examples of such packages, that are being maintained, but not updated since they're near perfect? I'd like to know if this is a real issue. It seems to me So what about this: Hackage could try to automatically collect and display information about the development status of packages that allow potential users to *guess* whether the package is maintained or not. Currently, potential users have to collect this information themselves. Here are some examples I have in mind: * Fetch the timestamp of the latest commit from the HEAD repo * Fetch the number of open issues from the issue tracker * Display reverse dependencies on the main hackage page * Show the timestamp of the last Hackage upload of the uploader Tillmann Those are good ideas. Some suggestions: I think we already have the timestamp of each upload, this already gives some information. Perhaps we could add a very simple feature saying how long ago that was and adding a warning color (like yellow if more than a year and red if more than two years). Reverse dependencies would certainly help a lot, but it works only for libraries, not for programs. (Although it's less likely that someone would search hackage for programs.) The problem with issue trackers is that (a) many packages don't have one, (b) there are many different issue trackers. Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Hackage checking maintainership of packages
Hi, on another thread there was a suggestion which perhaps went unnoticed by most: -- Forwarded message -- From: Niklas Hambüchen m...@nh2.me Date: 2013/5/4 ... I would even be happy with newhackage sending every package maintainer a quarterly question Would you still call your project X 'maintained'? for each package they maintain; Hackage could really give us better indications concerning this. This sounds to me like a very good idea. It could be as simple as If you consider yourself to be the maintainer of package X please just hit reply and send. If Hackage doesn't get an answer, it'd just would display some red text like This package seems to be unmaintained since D.M.Y. Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Hackage checking maintainership of packages
I'd say: - If a package has UNMAINTAINED (perhaps also DEPRECATED?) somewhere in its title/description, don't do anything. - Otherwise if the package hasn't been updated for past 3 months, send a quarterly reminder (including the information under what conditions the reminder is sent). 2013/5/5 Doug Burke dburke...@gmail.com On May 5, 2013 7:25 AM, Petr Pudlák petr@gmail.com wrote: Hi, on another thread there was a suggestion which perhaps went unnoticed by most: -- Forwarded message -- From: Niklas Hambüchen m...@nh2.me Date: 2013/5/4 ... I would even be happy with newhackage sending every package maintainer a quarterly question Would you still call your project X 'maintained'? for each package they maintain; Hackage could really give us better indications concerning this. This sounds to me like a very good idea. It could be as simple as If you consider yourself to be the maintainer of package X please just hit reply and send. If Hackage doesn't get an answer, it'd just would display some red text like This package seems to be unmaintained since D.M.Y. Best regards, Petr For those packages that give a repository, a query could be done automatically to see when it was last updated. It's not the same thing as 'being maintained', but is less annoying for those people with many packages on hackage. Doug ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Markdown extension for Haddock as a GSoC project
Hi, It seems that during the recent suggestions about what markup to choose (Markdown, Creole, Asciidoc, etc.), we've forgotten about one of the goals that seem very important to me for Haskell: the ability to write *math formulas*. I have experienced on StackExchange that just adding MathJAX to Markdown leads to many surprising errors that can be fixed only by strange hacks. Personally I'd incline to choose some existing, well-established markup language with formal specification that supports math (hopefully there is one). Extending Haddock with new features and a syntax for math formulas would certainly require to design such a specification, which isn't easy, and using an existing one would simplify the process a lot. Also I believe that newcomers to Haskell would definitely appreciate working with an existing markup language (and I'm sure not only them) instead of having to learn Haddock's syntax. Best regards, Petr 2013/5/2 Mateusz Kowalczyk fuuze...@fuuzetsu.co.uk -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/05/13 06:57, Ben wrote: sorry, i was only trying to make a helpful suggestion! just to clarify: i'm not championing asciitext (or any other format) -- i only heard about it recently in a comment on http://www.codinghorror.com/blog/2012/10/the-future-of-markdown.html i checked it out and it sounded cool, so i thought it'd be a helpful pointer to whomever is working on new haddock -- they are of course welcome to ignore it. totally understand that overmuch debate is not helpful (though i'm not sure it's fair to call it bikeshedding, since it is a primary feature of the proposed project!) best, ben On Apr 27, 2013, at 2:02 PM, Bryan O'Sullivan wrote: On Sat, Apr 27, 2013 at 1:47 PM, Ben midfi...@gmail.com wrote: asciidoc has been mentioned a few times in comments, i think it's worth looking at. This is the problem I was afraid of: for every markup syntax under the sun, someone will come along to champion it. The choice of one or N syntaxes is ultimately up to the discretion of the student, guided by their mentor. It is in our collective interest to avoid prolonging a bikeshed discussion on this, as a long inconclusive discussion risks dissuading any sensible student or mentor from wanting to pursue the project in the first place. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe These two posts are exactly why I believe that extending Haddock itself would be of more benefit than simply adding a Markdown extension to it: with addition to core features, integrating any of the N syntaxes that people want suddenly becomes the question of just writing reader and writer modules for Pandoc instead of a full project on marshalling yet another markup as an extension directly to Haddock. - -- Mateusz K. -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAEBAgAGBQJRggwfAAoJEM1mucMq2pqXHmAP/R2nHmXiNHDVqWEAoLQHSNeC psgcNm2hAclo6AxYprPsNHkqIUYh4HVpsc8FZw+RsAwkpUrGiaaMD/OTNB5857V+ 296lzHNOLNvge7B77FfVTa5wx1j2M+N0+pcOzcxr8qX5opfJNOcMPPtaXqD0nMS7 6EsBac/pQAjOHVYOTHEpsxAbl70s/QFBa/kW6tZPJmWKdHp6c3VmL5qx9CY9lZO4 1QKmyKqQMhxN0hmxcFHcYsa/IsohSAFewrs6JDErShn5ffIvtkhEM0UKVCBM26G4 Eu4Hadrv/AyoDT6UdtMgVllzY0XrykfLJ1nXzpp0QklYml0/SMmNrwqO9wfooMfF XKWiW2T8QWN5dFJO4kM9JA6UqpQ2uvrK6qWREL3jv8/jbEvg0WVko3zTW/BNzjF2 /Pn/9Z1vxYEee4A3Oa0sT7NGhKqK9KRtIgdfuXvTCnctvFYBxwtGHCcKuxgHVNNM GIJAqMtUtwr1Kjt37Gf0F+r1TBQfOsJL7tzRPayZKYPl7uA/ugrHHnYxL5JqIyAq bMUqLxAsDNW2tXIPzmNi4QYPqaopaUmwAD8IPvFk9e/1vI0QnU8b1URLjt5zl3O+ mFyWYTQd/UuaFOmOEmfLMJz+n2tRqL51LOCYcHwEjpH10WuTpX1DS3LWErcwppO5 bUZggQ5DwewgRIfCNEfS =nnP/ -END PGP SIGNATURE- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Diving into the records swamp (possible GSoC project)
Hi Adam, very nice idea. As the others, I'm curious why you chose to implement SORF in favor of the other ideas? I just read the SORF proposal, and I'm a bit concerned about what error messages would GHC issue when someone would type incorrect code involving such records. Currently Haskell's error messages already pose a barrier for newcomers (like No instance for (Num (a - a))), and if records are converted into those very complicated `Has` instances, type errors would be probably undecipherable even for moderate skilled Haskell users. Considering that records are a basic feature of Haskell and something that people with OOP background are familiar with, this could result in a feature that would without doubts deter many (if not most) newcomers. So do you think it would be possible to implement it in such a way that users get sensible type error messages? Best regards, Petr 2013/4/26 Adam Gundry adam.gun...@strath.ac.uk Hi, I am hoping to do a GSoC project this year working on GHC, and have been pointed in the direction of the records issue (in particular, the desire to overload field names). This has been discussed on-and-off for years, and while there are lots of ideas [1], little has been implemented in GHC itself. The plan would be to implement a solution to the narrow issue of overloaded field names, along the lines of Simon PJ's SORF proposal (on the wiki). This would provide a basis for experimentation with first-class record types. While there are still design issues to resolve, the broad plan is clear and I'm confident it can be implemented in a summer and without overly restricting future record system designs. Does this sound like a reasonable strategy? I'd appreciate comments and criticism, although arguing about the details of the design should perhaps wait. (A little about me: I'm a PhD student working on type inference for Haskell and dependent types, with about four years' Haskell experience including work on big type-system related projects. I am familiar with the theory behind GHC, but I haven't worked on the code before.) Thanks, Adam Gundry [1] http://hackage.haskell.org/trac/ghc/wiki/Records ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monad Transformer Space Leak
I tested it on GHC 6.12.1, which wasn't affected by the recent ackermann bug, but still it leaks memory. Petr Pudlak 2013/4/22 Clark Gaebel cgae...@uwaterloo.ca I don't have a copy of GHC HEAD handy, and don't have the time to set up the ecosystem myself to test this one bug. Would someone else with a copy lying around mind testing it out for me? Thanks, - Clark On Monday, April 22, 2013, Joachim Breitner wrote: Hi, Am Montag, den 22.04.2013, 16:44 -0400 schrieb Clark Gaebel: More interestingly, the problem goes away if I enable profiling. That's kind of worrisome. this part sounds similar than the recently discussed problem with the ackermann function (http://hackage.haskell.org/trac/ghc/ticket/7850) – maybe your code is only allocating stacks and nothing else? In that case you can try with GHC HEAD and see if the problem is fixed. Greetings, Joachim -- Joachim nomeata Breitner Debian Developer nome...@debian.org | ICQ# 74513189 | GPG-Keyid: 4743206C JID: nome...@joachim-breitner.de | http://people.debian.org/~nomeata ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] a library for abstract algebra?
Hi, is there a Haskell library for defining and working with algebraic structures such as groups, rings, fields, finite fields, vector spaces or modules? I found only several vector-related libraries, but they were all only over the field of real numbers (Double) and defined only vector spaces, not other algebraic structures. Thanks, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: rematch, an library for composable assertions with human readable failure messages
Hi tom, I had problems installing version 0.1.2.1 on GHC 7.4.1: Resolving dependencies... Downloading rematch-0.1.2.1... Configuring rematch-0.1.2.1... Building rematch-0.1.2.1... Preprocessing library rematch-0.1.2.1... [1 of 4] Compiling Control.Rematch.Formatting ( Control/Rematch/Formatting.hs, dist/build/Control/Rematch/Formatting.o ) [2 of 4] Compiling Control.Rematch.Run ( Control/Rematch/Run.hs, dist/build/Control/Rematch/Run.o ) [3 of 4] Compiling Control.Rematch ( Control/Rematch.hs, dist/build/Control/Rematch.o ) [4 of 4] Compiling Control.Rematch.QuickCheck ( Control/Rematch/QuickCheck.hs, dist/build/Control/Rematch/QuickCheck.o ) Control/Rematch/QuickCheck.hs:19:3: `exhaustive' is not a (visible) method of class `Testable' Failed to install rematch-0.1.2.1 cabal: Error: some packages failed to install: rematch-0.1.2.1 failed during the building phase. The exception was: ExitFailure 1 I installed v 0.1.2.0 without problems. Best regards, Petr 2013/4/16 Tom Crayford tcrayf...@gmail.com I kept on running into this thing where I was calling error in quickcheck to get good error messages about the things I was comparing. In Java land, this stuff is handled by Hamcrest: a library for composable assertions with good error messages. This library is basically a port of hamcrest's core api, but I've been very pleased with how it turned out. I've been using this in tests for production code for a month or so now, and I'm very pleased with it. Running a matcher (in this example in an hunit test) looks like this: expect [1] (is [1]) The core API is very simple: data Matcher a = Matcher { match :: a - Bool -- ^ A function that returns True if the matcher should pass, False if it should fail , description :: String -- ^ A description of the matcher (usually of its success conditions) , describeMismatch :: a - String -- ^ A description to be shown if the match fails. } This means you can add/write your own matchers happily, which occasionally means you can write *very* nice test code (here's an example of using a custom matcher for checking the state of an issue in a hypothetical issue tracking app): expect latestIssue (hasState Resolved) -- I removed the supporting code to make this assertion actually run, -- this email is already pretty long. There are numerous matchers (and functions for creating matchers) in the rematch library, including some composition functions that provide good failure messages. There are some shims to hook rematch into the common haskell test frameworks (specifically hunit and quickcheck). The two libraries are up on hackage: http://hackage.haskell.org/package/rematch http://hackage.haskell.org/package/rematch-text The code is all up on github: http://github.com/tcrayford/rematch I get rather frustrated when my tests give bad failure explanations, and using rematch goes a long way to fix that. Lastly, rematch is pretty isolated from test frameworks/etc, with a very small and easy to understand surface api. Hopefully it'll help with the thing I've seen in other languages (cough ruby cough) with every test framework reinventing this idea, and not all frameworks having all the matchers I want to use. Let me know if you have any feedback/thoughts Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: rematch, an library for composable assertions with human readable failure messages
2013/4/16 Ross Paterson r.pater...@city.ac.uk On Tue, Apr 16, 2013 at 10:17:48AM +0100, Tom Crayford wrote: The core API is very simple: data Matcher a = Matcher { match :: a - Bool -- ^ A function that returns True if the matcher should pass, False if it should fail , description :: String -- ^ A description of the matcher (usually of its success conditions) , describeMismatch :: a - String -- ^ A description to be shown if the match fails. } How about combining match and describeMismatch as a single function of type a - Match? Then you wouldn't need the precondition on describeMismatch. And this way we'd get `runMatch` right away in the data type: data Matcher a = Matcher { runMatch :: a - Match , description :: String } ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Set monad
One problem with such monad implementations is efficiency. Let's define step :: (MonadPlus m) = Int - m Int step i = choose [i, i + 1] -- repeated application of step on 0: stepN :: (Monad m) = Int - m (S.Set Int) stepN = runSet . f where f 0 = return 0 f n = f (n-1) = step Then `stepN`'s time complexity is exponential in its argument. This is because `ContT` reorders the chain of computations to right-associative, which is correct, but changes the time complexity in this unfortunate way. If we used Set directly, constructing a left-associative chain, it produces the result immediately: step' :: Int - S.Set Int step' i = S.fromList [i, i + 1] stepN' :: Int - S.Set Int stepN' 0 = S.singleton 0 stepN' n = stepN' (n - 1) `setBind` step' where setBind k f = S.foldl' (\s - S.union s . f) S.empty k See also: Constructing efficient monad instances on `Set` (and other containers with constraints) using the continuation monad http://stackoverflow.com/q/12183656/1333025 Best regards, Petr Pudlak 2013/4/11 o...@okmij.org The question of Set monad comes up quite regularly, most recently at http://www.ittc.ku.edu/csdlblog/?p=134 Indeed, we cannot make Data.Set.Set to be the instance of Monad type class -- not immediately, that it. That does not mean that there is no Set Monad, a non-determinism monad that returns the set of answers, rather than a list. I mean genuine *monad*, rather than a restricted, generalized, etc. monad. It is surprising that the question of the Set monad still comes up given how simple it is to implement it. Footnote 4 in the ICFP 2009 paper on ``Purely Functional Lazy Non-deterministic Programming'' described the idea, which is probably folklore. Just in case, here is the elaboration, a Set monad transformer. {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-} module SetMonad where import qualified Data.Set as S import Control.Monad.Cont -- Since ContT is a bona fide monad transformer, so is SetMonadT r. type SetMonadT r = ContT (S.Set r) -- These are the only two places the Ord constraint shows up instance (Ord r, Monad m) = MonadPlus (SetMonadT r m) where mzero = ContT $ \k - return S.empty mplus m1 m2 = ContT $ \k - liftM2 S.union (runContT m1 k) (runContT m2 k) runSet :: (Monad m, Ord r) = SetMonadT r m r - m (S.Set r) runSet m = runContT m (return . S.singleton) choose :: MonadPlus m = [a] - m a choose = msum . map return test1 = print = runSet (do n1 - choose [1..5] n2 - choose [1..5] let n = n1 + n2 guard $ n 7 return n) -- fromList [2,3,4,5,6] -- Values to choose from might be higher-order or actions test1' = print = runSet (do n1 - choose . map return $ [1..5] n2 - choose . map return $ [1..5] n - liftM2 (+) n1 n2 guard $ n 7 return n) -- fromList [2,3,4,5,6] test2 = print = runSet (do i - choose [1..10] j - choose [1..10] k - choose [1..10] guard $ i*i + j*j == k * k return (i,j,k)) -- fromList [(3,4,5),(4,3,5),(6,8,10),(8,6,10)] test3 = print = runSet (do i - choose [1..10] j - choose [1..10] k - choose [1..10] guard $ i*i + j*j == k * k return k) -- fromList [5,10] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GSoC Project Proposal: Markdown support for Haddock
Hi, I also support the idea of having Markdown for Haddock. Using some well established markup language would make Haddock much easier to adopt and use. While I like the idea of allowing any markup language (let's say supported by Pandoc) and freedom it gives to developers, it also has also drawbacks: It makes contributing more difficult, if a project uses some wierd, non-standard markup language. Concerning math expressions, what about using Markdown with MathJAX, like math.stackexchange.com does? Best regards, Petr Pudlak 2013/4/5 Andrew Butterfield andrew.butterfi...@scss.tcd.ie I'm not proposing the LaTeX is used for hyperlinking the reference - hence my comment about nicely integrating Perhaps a \begin{haddock} ... \end{haddock} environment* ? * This would only affect those using LaTeX/lhs - everyone else could haddock** as usual ** haddock = whatever markdow/up/sideways scheme you guys come up with... On 5 Apr 2013, at 16:22, Aleksey Khudyakov wrote: On 5 April 2013 12:20, Andrew Butterfield andrew.butterfi...@scss.tcd.ie wrote: On 4 Apr 2013, at 22:53, Aleksey Khudyakov wrote: If we are going to change haddock syntax we should add ability to add math formulae to documentation. It's not currently possible and it makes documenting numeric code properly difficult. How about support for .lhs files? - both those with bird-tracks (which I don't use anymore) and \begin{code}...\end{code} (which I do use). My .lhs files are also LaTeX sources - I guess some way to nicely integrate haddock markup/down/whatever with LaTeX stuff would be needed I'm not sure that it would help. If we to use haddock markup it need to support math typesetting. And LaTeX IMHO isn't right tool for creating hyperlinked API reference ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Lero@TCD, Head of Foundations Methods Research Group Director of Teaching and Learning - Undergraduate, School of Computer Science and Statistics, Room G.39, O'Reilly Institute, Trinity College, University of Dublin http://www.scss.tcd.ie/Andrew.Butterfield/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Need some advice around lazy IO
Hi Kashyap, you could also use iteratees or conduits for a task like that. The beauty of such libraries is that they can ensure that a resource is always properly disposed of. See this simple example: https://gist.github.com/anonymous/5183107 It prints the first line of each file given as an argument. After each line is printed, the `fileConduit` pipe ensures that the handle is closed. It also makes the program nicely composable. Best regards, Petr import Control.Monad import Control.Monad.Trans.Class import Control.Monad.IO.Class import Data.Conduit import Data.Conduit.List import System.Environment import System.IO {- | Accept file paths on input, output opened file handle, and ensure that the - handle is always closed after its downstream pipe finishes whatever work on it. -} fileConduit :: MonadResource m = IOMode - Conduit FilePath m Handle fileConduit mode = awaitForever process where process file = bracketP (openFile file mode) closeWithMsg yield closeWithMsg h = do putStrLn Closing file hClose h {- | Print the first line from each handle on input. Don't care about the handle. -} firstLine :: MonadIO m = Sink Handle m () firstLine = awaitForever (liftIO . (hGetLine = putStrLn)) main = do args - getArgs runResourceT $ sourceList args =$= fileConduit ReadMode $$ firstLine 2013/3/17 C K Kashyap ckkash...@gmail.com Hi, I am working on an automation that periodically fetches bug data from our bug tracking system and creates static HTML reports. Things worked fine when the bugs were in the order of 200 or so. Now I am trying to run it against 3000 bugs and suddenly I see things like - too many open handles, out of memory etc ... Here's the code snippet - http://hpaste.org/84197 It's a small snippet and I've put in the comments stating how I run into out of file handles or simply file not getting read due to lazy IO. I realize that putting ($!) using a trial/error approach is going to be futile. I'd appreciate some pointers into the tools I could use to get some idea of which expressions are building up huge thunks. Regards, Kashyap ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Are there any reasons against using ~ when matching one-constructor data types?
Dear Haskellers, b) A related suggestion would be the addition of an irrefutable swap, (swap'?), defined as swap ~(a,b) = (b,a), and its addition to Prelude for the same reasons. If I define a function that matches on a single-constructor data type, such as (,), is there any reason against using ~? Like f (a,b) = ... instead of f ~(a,b) = ... ? I've seen that not using ~ can lead to problems sometimes, but not the other way around. (Of course changing the semantics of existing functions such as `swap` is problematic, my question targets the problem in general.) Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] RFC: rewrite-with-location proposal
2013/2/25 Michael Snoyman mich...@snoyman.com At that point, we've now made two changes to REWRITE rules: 1. They can takes a new ALWAYS parameters. 2. There's a new, special identifier currentLocation available. What would be the advantage is of that approach versus introducing a single new REWRITE_WITH_LOCATION pragma? Just a remark: 'currentLocation' is not a function (it's a special keyword) but behaves like one - it returns some kind of value. But it's not referentially transparent - it returns a different value depending on where it's used. This is something that I really don't expect from Haskell. So having it return `IO Location` seems therefore much better option. And if someone really wants to get the location as a pure value, (s)he can simply wrap it with `unsafePerformIO`, which signals code readers to be careful with that part. Best regards, Petr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] generalized, tail-recursive left fold that can finish tne computation prematurely
Dear Haskellers, 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). - `foldl` is also unsuitable, because it always traverses the whole list. I came up with the following tail-recursive generalization of `foldl` that allows exiting the computation prematurely: foldlE :: (a - c) - (a - b - Either c a) - Either c a - [b] - c foldlE f g = fld where fld (Left c) _ = c fld (Right a) []= f a fld (Right a) (x:xs)= fld (g a x) xs `foldl` can be defined from it as foldl'' :: (a - b - a) - a - [b] - a foldl'' f z = foldlE id ((Right .) . f) (Right z) and `!!` as: -- Checks for a negative index omitted for brevity. index :: Int - [a] - a index i = foldlE (error $ No such index) f (Right i) where f 0 x = Left x f n _ = Right (n - 1) Is something like that already available somewhere? Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] generalized, tail-recursive left fold that can finish tne computation prematurely
Dear Haskellers, 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). - `foldl` is also unsuitable, because it always traverses the whole list. I came up with the following tail-recursive generalization of `foldl` that allows exiting the computation prematurely: foldlE :: (a - c) - (a - b - Either c a) - Either c a - [b] - c foldlE f g = fld where fld (Left c) _ = c fld (Right a) []= f a fld (Right a) (x:xs)= fld (g a x) xs `foldl` can be defined from it as foldl'' :: (a - b - a) - a - [b] - a foldl'' f z = foldlE id ((Right .) . f) (Right z) and `!!` as: -- Checks for a negative index omitted for brevity. index :: Int - [a] - a index i = foldlE (error $ No such index) f (Right i) where f 0 x = Left x f n _ = Right (n - 1) Is something like that already available somewhere? Best regards, Petr Pudlak ___ 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
Thanks Roman and Andres for the tip. I knew the trick with accumulating a function, but I had never imagined it could work so efficiently. I thought the problem with using foldr would be that the function would be neither tail recursive nor efficient and so I hadn't even tried. Apparently that was wrong. After your suggestion I checked its performance and how it compiles to core and to my surprise GHC optimizes the whole thing into a most-efficient tail recursive function! Best regards, Petr 2013/2/18 Roman Cheplyaka r...@ro-che.info * Petr Pudlįk petr@gmail.com [2013-02-18 17:10:26+0100] Dear Haskellers, 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). - `foldl` is also unsuitable, because it always traverses the whole list. Every structurally-recursive function is definable through foldr, because foldr *is* the structural recursion (aka catamorphism) operation for lists. Here the trick is to make the accumulator a function. This way you can pass a value from left to right. Something like foldr (\x rest n - ...) id list 0 I'll leave filling in the dots as an exercise. Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] arrow notation
2013/2/11 Ertugrul Söylemez e...@ertes.de Petr Pudlák petr@gmail.com wrote: class Arrow a = ArrowDelay a where delay :: a b c - a () (b - c) force :: Arrow a = a () (b - c) - a b c Perhaps it would be convenient to have ArrowDelay and the corresponding conversions included in the library so that defining and using Applicative instances for arrows would become more straightforward. I appreciate the idea from a theoretical standpoint, but you don't actually have to define an ArrowDelay instance for the notation to work. The compiler can't check the laws anyway. That's true. But I'm afraid that without the ArrowDelay constraint people would think that every arrow forms an applicative functor and eventually get into hard-to-trace problems with failing the applicative laws. The compiler can't check the laws, so somebody else has to. Should it be users of an arrow or its authors? Without the constraint, the burden would be on the users: Before using the applicative instance, check if the arrow is really an applicative functor. That's something users of a library aren't supposed to do. With the constraint, the burden would be on the authors of the arrow - they'd have to define the instance and be responsible for satisfying the laws. I feel this is more appropriate. Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] arrow notation
2013/2/11 Ertugrul Söylemez e...@ertes.de ... ## Applicative One of the main bottlenecks of arrows is the heavy tuple handling, but most (if not all) arrows form a family of applicative functors. I noticed a huge speedup by moving from arrow style to applicative style where possible: liftA2 (+) (lmap f c) (fmap g d) is often much faster than: arr (uncurry (+)) . (c . arr f arr g . d) Besides being more readable it sometimes improved the performance of my code by an order of magnitude. So perhaps check to see if the category forms an applicative functor. If it does, you can get along without Arrow entirely. I've been reading *Idioms are oblivious, arrows are meticulous, monads are promiscuous* recently, and if I understand it correctly, an arrow forms an applicative functor if it's possible to define a delaying operation on it, which separates the arrow's effect from its computation: class Arrow a = ArrowDelay a where delay :: a b c - a () (b - c) -- Definable for any arrow: force :: Arrow a = a () (b - c) - a b c force af = (,) () ^ first af ^ uncurry ($) and satisfying `force . delay = id = delay . force`. While the implementation of Applicative can be defined without actually using `delay`: newtype ArrowApp a b c = ArrowApp (a b c) instance Arrow a = Functor (ArrowApp a b) where fmap f (ArrowApp a) = ArrowApp (a ^ f) instance ArrowDelay a = Applicative (ArrowApp a b) where pure x = ArrowApp $ arr (const x) (ArrowApp af) * (ArrowApp ax) = ArrowApp $ (af ax) ^ uncurry ($) I believe it only satisfies the laws only if the arrow satisfies delay/force laws. Perhaps it would be convenient to have ArrowDelay and the corresponding conversions included in the library so that defining and using Applicative instances for arrows would become more straightforward. Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] arrow notation
2013/2/9 Conal Elliott co...@conal.net On Thu, Feb 7, 2013 at 5:41 PM, Ross Paterson r...@soi.city.ac.uk wrote: It's hard to imagine arrow notation without arr (or at least contravariance in the first argument of the arrow) because forming expressions using the local environment is so central to it. That is, I can't imagine what things you are trying to write in that situation. What I have in mind is a small collection of methods including fst snd (and similarly for sums) that could be defined via arr but could instead form the basis of translating restricted arrow notation for (pseudo-)arrows that don't support arr. I also support this idea, I'd appreciate such a generalization. As an example, where it would be useful: One of my students was working on a (very nice) project where he used Haskell as a DSL for generating a FRP-like javascript code. The arrow notation without arr would be ideal for this situation. He couldn't implement arr as it would require to translate an arbitrary Haskell function to JS. So having a more general variant of Arrow without arr and with a collection of methods sufficient for the arrow notation would be quite helpful. (I wonder what methods would have to be included in the collection.) Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Control.Monad provisional?
Dear Haskellers, Looking at Control.Monad: http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/Control-Monad.html I see: Stability provisional. I checked some older versions and it's the same. This feel somewhat unsettling - if Control.Monad is provisional, do we have any stable packages at all? Best regards, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] A list of Haskell-related quotes?
Dear haskellers, over the time I've read many funny or inspiring quotes related to Haskell, but I forgot them later. For example I vaguely remember: - What I really like about Haskell: It's completely unlike PHP. - To learn Haskell your brain will have to get seriously rewired. Does anybody collect them or know about such a collection? Thanks, Petr Pudlak ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe