Re: [Haskell-cafe] Lenses: Should I declare Getters?
On Tue, Sep 10, 2013 at 1:31 AM, Charlie Paul charli...@gmail.com wrote: I've been looking through Edward Kmett's lens library, and I'm a bit befuddled about Getters. In my own code, why would I want to have something be a Getter instead of a plain function? As far as I can see, a plain function is simpler to use, and can be converted to a Getter with to if we want to use it as a Fold. Is there a situation where writing a Getter is superior than writing a function, then lifting it as needed? As I understand it, you'd be better off declaring a function and then using to. Getters are a midpoint between a Lens and a Fold. With a lens, you can read and write a single value in a larger structure. With a fold, you can read a sequence of values in a larger structure. The need for getters comes from to. myLens . to f cannot be a lens, because modifying the value it points to would require an inverse for f, but if making it a fold would lose the property that it points to exactly one value. So a getter lets you read a single value in a larger structure. That being said, view (myLens . to f) is isomorphic to f . view myLens. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Applicative is like an Arrow
On Sat, Aug 17, 2013 at 8:23 AM, Mathijs Kwik math...@bluescreen303.nlwrote: damodar kulkarni kdamodar2...@gmail.com writes: Thanks for this nice analogy and explanation. This brings monad transformers to my mind. without monad transformers, the monads are bit crippled in their applicability (please correct me if I am wrong) and with monad transformers the code becomes to some extent ugly (again, please correct me if I am wrong) I wonder, where and how the Monad transformers fit in here? Well, I'm glad you all liked my explanation =) Let me first correct 1 stupid mistake I wrote in the first paragraph: - Every idiom is an arrow and every arrow is a monad, but not the other way around. should obviously be: + Every Monad is an Arrow (with ArrowApply) and every Arrow is an Idiom, but not the other way around. Every Idiom defines a static arrow: newtype Static f a b = Static (f (a - b)) instance Applicative f = Arrow (Static f) Similarly, every arrow defines an idiom: newtype WrappedArrow a b c = WrappedArrow (a b c) instance Arrow a = Applicative (WrappedArrow a b) The difference is that WrappedArrow (Static f) () is essentially the same as f, but Static (WrappedArrow a ()) is not necessarily the same as a. Basically, if an arrow can be made an instance of ArrowDelay, then it is no more powerful than an Idiom (meaning anything you can write using the arrow combinators can also be written with just the Applicative combinators): class Arrow a = ArrowDelay a where delay :: a b c - a () (b - c) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Can not use ST monad with polymorphic function
On Thu, Nov 29, 2012 at 7:50 AM, Dmitry Kulagin dmitry.kula...@gmail.comwrote: Thank you, MigMit! If I replace your type FoldSTVoid with: data FoldMVoid = FoldMVoid {runFold :: Monad m = (Int - m ()) - m ()} then everything works magically with any monad! That is exactly what I wanted, though I still do not quite understand why wrapping the type solves the problem Short answer: It's because GHC's type system is predicative. Basically, quantified types can't be given as arguments to type constructors (other than -, which is its own thing). I'm not entirely sure why, but it apparently makes the type system very complicated from a theoretical standpoint. By wrapping the quantified type in a newtype, the argument to IO becomes simple enough not to cause problems. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type variable in class instance
I'm not sure I understand On Tue, Sep 11, 2012 at 11:06 AM, Corentin Dupont corentin.dup...@gmail.com wrote: Yes. That's fantastic! This GADT is the missing piece of my puzzle. I transformed a bit your solution, polluting it with some classes instances and fleshing the functions: data Player = Arrive | Leave deriving (Show, Typeable, Eq) data Message m = Message String deriving (Show, Typeable, Eq) data Data a where PlayerData :: Int - Data Player MessageData :: m - Data (Message m) data Handler where Handler :: (Typeable e) = e - (Data e - IO ()) - Handler instance forall e. (Typeable e) = Typeable (Data e) where typeOf _ = mkTyConApp (mkTyCon( (Expression.EventData ( ++ (show $ typeOf (undefined::e))) ++ ) )) [] addEvent :: (Typeable e) = e - (Data e - IO ()) - [Handler] - [Handler] addEvent e h hs = (Handler e h) : hs triggerEvent :: (Eq e, Typeable e) = e - Data e - [Handler] - IO () triggerEvent e d hs = do let filtered = filter (\(Handler e1 _) - e1 === e) hs mapM_ f filtered where f (Handler _ h) = case cast h of Just castedH - do castedH d Nothing - return () viewEvent :: (Typeable e) = e - IO() viewEvent event = do case cast event of Just (a :: Player) - putStrLn $ Player ++ show a Nothing - return () case cast event of (Just (Message s)) - putStrLn $ Player ++ s Nothing - return () Unfortunately, I still cannot pattern match on the events to view them (viewEvent won't compile)... Mixing GADTs and Typeable seems like a bad idea. If you really don't want to put viewEvent in the Event typeclass, but the class of events is closed, you could use a GADT to witness the event type. class Event e where eventType :: EventType e ... data EventType e where PlayerEvent :: EventType Player MessageEvent :: EventType (Message m) viewEvent :: Event e = e - IO () viewEvent = viewEvent' eventType viewEvent' :: EventType e - e - IO () viewEvent' PlayerEvent e = ... viewEvent' MessageEvent (Message s) = ... -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Platform Versioning Policy: upper bounds are not our friends
As I see it, there are four possibilities for a given version of dependency: 1. The version DOES work. The author (or some delegate) has compiled the package against this version and the resulting code is considered good. 2. The version SHOULD work. No one has tested against this version, but the versioning policy promises not to break anything. 3. The version MIGHT NOT work. No one has tested against this version, and the versioning policy allows breaking changes. 4. The version DOES NOT work. This has been tested and the resulting code (if any) is considered not good. Obviously, cases 1 and 4 can only apply to previously released versions. The PVP requires setting upper bounds in order to distinguish cases 2 and 3 for the sake of future compatibility. Leaving off upper bounds except when incompatibility is known essentially combines cases 2 and 3. So there are two failure modes: I. A version which DOES work is outside the bounds (that is, in case 3). I think eliminating case 3 is too extreme. I like the idea of temporarily overriding upper bounds with a command-line option. The danger here is that we might actually be in case 4, in which case we don't want to override the bounds, but requiring an explicit override gives users a chance to determine if a particular version is disallowed because it is untested or because it is known to be incompatible. II. A version which DOES NOT work is inside the bounds (that is, in case 2). This happens when a package does not follow its own version policy. For example, during the base-4 transition, a version of base-3.0 was released which introduced a few breaking changes (e.g., it split the Arrow class). Alternately, a particular version might be buggy. This can already be handled by adding constraints on the command line, but it's better to release a new version of the package with more restrictive constraints. (This might not be enough, though. If I release foo-1.0.0 which depends on bar-1.0.*, and then bar-1.0.1 is released with with a bug or breaking change, I can release foo-1.0.0.1 which disallows bar-1.0.1. But we need some way of preventing cabal from using foo-1.0.0. Can Hackage deprecate specific versions?) On Wed, Aug 22, 2012 at 9:18 AM, Leon Smith leon.p.sm...@gmail.com wrote: I think we actually agree more than we disagree; I do think distinguishing hard and soft upper bounds (no matter what they are called) would help, and I'm just trying to justify them to some of the more dismissive attitudes towards the idea The only thing I think we (might) disagree on is the relative importance of distinguishing hard and soft bounds versus being able to change bounds easily after the fact (and *without* changing the version number associated with the package.) And on that count, given the choice, I pick being able to change bounds after the fact, hands down. I believe this is more likely to significantly improve the current situation than distinguishing the two types of bound alone. However, being able to specify both (and change both) after the fact may prove to be even better. Best, Leon On Sat, Aug 18, 2012 at 11:52 PM, wren ng thornton w...@freegeek.org wrote: On 8/17/12 11:28 AM, Leon Smith wrote: And the difference between reactionary and proactive approaches I think is a potential justification for the hard and soft upper bounds; perhaps we should instead call them reactionary and proactive upper bounds instead. I disagree. A hard constraint says this package *will* break if you violate me. A soft constraint says this package *may* break if you violate me. These are vastly different notions of boundary conditions, and they have nothing to do with a proactive vs reactionary stance towards specifying constraints (of either type). The current problems of always giving (hard) upper bounds, and the previous problems of never giving (soft) upper bounds--- both stem from a failure to distinguish hard from soft! The current/proactive approach fails because the given constraints are interpreted by Cabal as hard constraints, when in truth they are almost always soft constraints. The previous/reactionary approach fails because when the future breaks noone bothered to write down when the last time things were known to work. To evade both problems, one must distinguish these vastly different notions of boundary conditions. Hard constraints are necessary for blacklisting known-bad versions; soft constraints are necessary for whitelisting known-good versions. Having a constraint at all shows where the grey areas are, but it fails to indicate whether that grey is most likely to be black or white. -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org
Re: [Haskell-cafe] ANNOUNCE: set-monad
On Sun, Jun 17, 2012 at 2:26 AM, Tillmann Rendel ren...@informatik.uni-marburg.de wrote: Hi, David Menendez wrote: As you noticed, you can get somewhat better performance by using the combinators that convert to S.Set internally, because they eliminate redundant computations later on. Somewhat better? My example was three times faster, and I guess that the fast variant is O(n) and the slow variant is O(n²). So I expect that for some applications, the Set interface is more than fast enough and the MonadPlus-interface is much too slow. Yes, that should have been significantly better. (Why is unioned faster then numbers? Is union doing some rebalancing? Can I trigger that effect directly?) It's because mplus a b= f turns into mplus (a= f) (b= f), whereas unioned takes the union before calling f. Here, you compare mplused to unioned, but in the parentheses, I asked about numbers and unioned (from my last email). You're right. That may have been caused by the time to compute numbers itself; I saw that numbers `times` numbers was faster than unioned `times` unioned the second time I ran it. Additionally, I haven't done any serious performance testing, but there also seems to be a speedup when the following lines are added to run: run (Bind (Plus (Prim sa) mb) f) = run (Bind (S.union sa (run mb)) f) run (Bind (Plus ma (Prim sb)) f) = run (Bind (S.union (run ma) sb) f) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: set-monad
On Sat, Jun 16, 2012 at 3:57 AM, Tillmann Rendel ren...@informatik.uni-marburg.de wrote: George Giorgidze wrote: I would like to announce the first release of the set-monad library. On Hackage: http://hackage.haskell.org/package/set-monad Very cool. Seems to work fine. But I am wondering about the impact of using your package on asymptotic complexity (and thereby, on performance). For programs using only the Monad/MonadPlus interface, I would expect it to have the same asymptotic complexity as [] or Cont (S.Set a). As you noticed, you can get somewhat better performance by using the combinators that convert to S.Set internally, because they eliminate redundant computations later on. (Why is unioned faster then numbers? Is union doing some rebalancing? Can I trigger that effect directly?) It's because mplus a b = f turns into mplus (a = f) (b = f), whereas unioned takes the union before calling f. You can force this by defining: simplify :: (Ord a) = Set a - Set a simplify = Prim . run Unfortunately, there doesn't seem to be any equivalent of Prim in the exported interface. I guess doing simplify = union empty would work. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monads, do and strictness
On Sat, Jan 21, 2012 at 1:45 PM, David Barbour dmbarb...@gmail.com wrote: On Sat, Jan 21, 2012 at 10:08 AM, Roman Cheplyaka r...@ro-che.info wrote: * David Barbour dmbarb...@gmail.com [2012-01-21 10:01:00-0800] As noted, IO is not strict in the value x, only in the operation that generates x. However, should you desire strictness in a generic way, it would be trivial to model a transformer monad to provide it. Again, that wouldn't be a monad transformer, strictly speaking, because monads it produces violate the left identity law. It meets the left identity law in the same sense as the Eval monad from Control.Strategies. http://hackage.haskell.org/packages/archive/parallel/3.1.0.1/doc/html/src/Control-Parallel-Strategies.html#Eval The Eval monad has the property: return undefined = const e = e. From what I can tell, your proposed monads do not. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Wed, Dec 21, 2011 at 12:20 PM, Conor McBride co...@strictlypositive.org wrote: On 21 Dec 2011, at 14:07, Erik Hesselink hessel...@gmail.com wrote: On Wed, Dec 21, 2011 at 14:10, Bas van Dijk v.dijk@gmail.com wrote: The semantics of Maybe are clear: it's failure-and-prioritized-choice. Are you sure? Yes. There are (at least) four Monoid instances for Maybe [1]. With a direct instance for Maybe and its Dual you have only covered two. Types don't just give data a representation: types evoke structure. The data stored by Maybe can be made into a monoid in several ways, but the failure-management role of Maybe makes just one of them appropriate. This is my view as well. While it's true that the current Monoid instance for Maybe is the only one that isn't captured by an obvious adaptor, I think we'd be better off with a dedicated type for that sort of semigroup-to-monoid transformation. Those obvious adaptors, by the way: newtype MPlus m a = MPlus (m a) instance MonadPlus m = Monoid (MPlus m a) where mempty = MPlus mzero mappend (MPlus x) (MPlus y) = MPlus (mplus x y) newtype LiftA2 m a = LiftA2 (m a) instance (Applicative m, Monoid a) = Monoid (LiftA2 m a) where mempty = LiftA2 (pure mempty) mappend (LiftA2 x) (LiftA2 y) = LiftA2 (liftA2 mappend x y) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Wed, Dec 21, 2011 at 12:37 PM, wren ng thornton w...@freegeek.org wrote: On 12/19/11 10:20 PM, David Menendez wrote: On Mon, Dec 19, 2011 at 6:37 PM, wren ng thorntonw...@freegeek.org wrote: On 12/14/11 10:58 PM, Gregory Crosswhite wrote: Of course, this is not a simple change at all because it would have to be done in such a way as to respect the ordering of actions --- that is, we can't have each action executed only when the corresponding element of the list demanded is forced, or else actions would undesirably interleave. Therein lies the issue. To put this in a monadic context, this is the same reason why we can't just say: evalState (repeatM getNext) init e.g., to generate an infinite list of pseudorandom numbers and then discard the final seed because we have all the numbers we'll ever need. Sure you can. Just make sure you're using a non-strict state monad. Fair enough. I over-simplified the example I had in mind, which cannot be evaded so easily. Though it's worth pointing out that your solution relies on the specific property I mentioned (later in the same email), namely that it is safe to perform the evaluation of lazy state at any point we desire, because it will not interact with other side-effects[1]. Thus, this happens to be one of the monads which has the property necessary for being able to perform the reordering desired by the OP. However, if we try using your 'repeatM' for other monads it is unlikely to work--- and for the same reasons that 'many' and 'some' are problematic for Maybe and lists. Yes, sequence . repeat is only sensible for non-strict monads, which are fairly uncommon. (Identity, State, Reader, Writer, infinite search, and various combinations thereof are the only ones I'm aware of.) The situation is exactly analogous to many and some, which are only meaningful for certain values in certain types, as well as to functions like fix and folder, which can diverge if given inappropriate arguments. If there were a lot of code that was (1) meaningfully generic over non-strict monads and (2) diverged for strict monads, it might make sense to declare a subclass and restrict those functions to non-strict monads. That won't stop someone from trying to call sequence on an infinite list, but it does express an important precondition of the code in the type. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Alternative versus Monoid
On Wed, Dec 21, 2011 at 8:10 AM, Bas van Dijk v.dijk@gmail.com wrote: On 16 December 2011 16:26, Yves Parès limestr...@gmail.com wrote: 1) What about the First type? Do we {-# DEPRECATE #-} it? Personnaly, I'm in favor of following the same logic than Int: Int itself is not a monoid. You have to be specific: it's either Sum or Mult. It should be the same for Maybe: we remove its instance of Monoid, and we only use First and Last. The reason you need to be specific with Int is that it's not clear which semantics (sum or product) you want. The semantics of Maybe are clear: it's failure-and-prioritized-choice. Changing the order of the arguments of mappend should be the job of Dual. If we really want to drop the Monoid instance for Maybe and keep First and Last and also want to be consistent we should also drop the Monoid instances of [a], a-b, Endo a and of all the tuples. Interestingly, every one of these examples can been seen as an adaptor from another class. For [a], the monoid is (mzero,mplus). For a - b and the tuples, the monoid is (pure mempty, liftA2 mappend). For Endo, the monoid is (id, (.)) (from Category) The current monoid instances for [a], a - a, and the tuples feel like natural choices (in contrast to Maybe), but knowing which operations are used requires some understanding of the design history of the library. That's why I recommend only using mempty and mappend with polymorphic code. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Alternative] change some/many semantics
On Mon, Dec 19, 2011 at 6:37 PM, wren ng thornton w...@freegeek.org wrote: On 12/14/11 10:58 PM, Gregory Crosswhite wrote: Of course, this is not a simple change at all because it would have to be done in such a way as to respect the ordering of actions --- that is, we can't have each action executed only when the corresponding element of the list demanded is forced, or else actions would undesirably interleave. Therein lies the issue. To put this in a monadic context, this is the same reason why we can't just say: evalState (repeatM getNext) init e.g., to generate an infinite list of pseudorandom numbers and then discard the final seed because we have all the numbers we'll ever need. Sure you can. Just make sure you're using a non-strict state monad. import Control.Monad.Identity import Control.Monad.State.Lazy import System.Random repeatM :: Monad m = m a - m [a] repeatM = sequence . repeat nextM :: RandomGen g = StateT g Identity Int nextM = StateT $ Identity . next *Main g - getStdGen *Main let ints = runIdentity $ evalStateT (repeatM nextM) g *Main :t ints ints :: [Int] *Main take 5 ints [1259974427,117524251,96384700,1814821362,997859942] *Main take 10 ints [1259974427,117524251,96384700,1814821362,997859942,2058526379,835643552,1075525457,727974455,388071455] *Main ints !! 100 271901956 -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ismzero operator possible without equal constraint
On Sat, Dec 3, 2011 at 3:55 PM, Antoine Latter aslat...@gmail.com wrote: On Sat, Dec 3, 2011 at 10:55 AM, edgar klerks edgar.kle...@gmail.com wrote: Hi list, I am using MonadSplit (from http://www.haskell.org/haskellwiki/New_monads/MonadSplit ) for a project and now I want to make a library out of it. This seems to be straightforward, but I got stuck when I tried to move miszero out of the class: miszero :: m a - Bool It tests if the provided monad instance is empty. My naive attempt was: You can write: miszero :: MonadPlus m = m a - m Bool miszero m = (m return False) | return True but that will invoke any monadic effects as well as determining the nature of the value, which may not be what you want. It's almost certainly not what you want for the list monad. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Interpreter with Cont
On Mon, Nov 21, 2011 at 2:13 PM, Tim Baumgartner baumgartner@googlemail.com wrote: Free Monads. It's amazing to be confronted again with notions I learned more than ten years ago for groups. I have to admit that I'm probably not yet prepared for a deeper understanding of this, but hopefully I will return to it later ;-) Is Cont free as well? I guess so because I heard it's sometimes called the mother of all monads. As I understand it, Cont is not a free monad, but there is a connection between the ideas. Certainly, any free monad can be easily reimplemented using Cont. Here's how you might implement your monad using Cont, type InteractionM a b = Cont (Interaction a b) exit b = Cont $ \k - Exit b output b = Cont $ \k - Output b (k ()) input= Cont $ \k - Input k runM m = runCont m Exit That's very similar to the free monad's implementation, only with the continuation replacing Val. exit b = Wrap $ ExitF b output b = Wrap $ OutputF b (Val ()) input= Wrap $ InputF Val runM m = foldFree Exit roll m The Cont-based version has essentially taken the work performed in foldFree and distributed it to return and (=). This eliminates the intermediate data structures, resulting in a more efficient implementation. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Interpreter with Cont
On Sat, Nov 19, 2011 at 3:29 PM, Felipe Almeida Lessa felipe.le...@gmail.com wrote: On Sat, Nov 19, 2011 at 6:08 PM, Tim Baumgartner baumgartner@googlemail.com wrote: I have not yet gained a good understanding of the continuation monad, but I wonder if it could be used here. What would a clean solution look like? Perhaps there are other things that need to be changed as well? Your 'Interaction' data type is actually an instance of the more general operational monad (as named by Heinrich Apfelmus) or prompt monad (as named by Ryan Ingram). Both of which are just disguised free monads. For reference: data Free f a = Val a | Wrap (f (Free f a)) foldFree :: Functor f = (a - b) - (f b - b) - Free f a - b foldFree v w (Val a) = v a foldFree v w (Wrap t) = w $ fmap (foldFree v w) t instance Functor f = Monad (Free f) where return = Val m = f = foldFree f Wrap m To use Free, just find the signature functor for Interaction by replacing the recursive instances with a new type variable, data InteractionF a b x = ExitF b | OutputF b x | InputF (a - x) instance Functor (InteractionF a b) where fmap f (ExitF b) = ExitF b fmap f (OutputF b x) = OutputF b (f x) fmap f (InputF g)= InputF (f . g) roll :: InteractionF a b (Interaction a b) - Interaction a b roll (ExitF b) = Exit b roll (OutputF b x) = Output b x roll (InputF g)= Input g type InteractionM a b = Free (InteractionF a b) runM :: InteractionM a b b - Interaction a b runM = foldFree Exit roll exit :: b - InteractionM a b c exit b = Wrap (ExitF b) output :: b - InteractionM a b () output b = Wrap (OutputF b (Val ())) input :: InteractionM a b a input = Wrap (InputF Val) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data Flow Programming in FP
On Tue, Jun 21, 2011 at 12:14 PM, Edward Kmett ekm...@gmail.com wrote: The essence of data flow programming describes how you can use comonads to model the semantics of dataflow languages. One of the best stops from there is probably, Dave Menendez's response on the Haskell mailing list back in 2005 summarized how one can move from building a semantics for dataflow programming using comonads to actually implementing dataflow programming directly using comonads. This is useful if you don't want to write a dataflow language compiler or interpreter, but instead just want to write some dataflow code in the middle of your program as an embedded domain-specific language. http://www.haskell.org/pipermail/haskell/2005-September/016502.html Comonads are useful for describing dataflow operations and for making simple implementations, but they can have serious performance problems if your goal is to obtain intermediate results. Still, it's useful to see what sorts of things are possible with comonads and how they translate into other, more efficient implementations. I should also note a few errors in my 2005 e-mail: 1. CoKleisli arrows are *not* an instance of ArrowApply, as they do not satisfy the composition law. That is, app . arr ((h .) *** id) /= h . app 2. Defining ArrowLoop does not require a zip operation. You can define the instance like so: instance Comonad c = ArrowLoop (Cokleisli c) where loop f = C $ fst . f' where f' = unC f . coextend (extract snd . f') This incidentally, was inspired by a more recent definition of cfix, cfix :: Comonad f = (f (a,b) - b) - f a - b cfix f = f . coextend (\c - (extract c, cfix f c)) (Exercise: define the cfix in my 2005 email in terms of this one, and vice versa.) 3. You don't need cfix to write recursive comonadic code. For example, pos (which is initially one and then increments), can be defined using cfix: pos :: History a - Int pos = cfix (\ctx - 1 + 0 `fby` fmap snd ctx) but it can also be defined using Haskell's recursion: pos ctx = 1 + 0 `fby` pos ctx 4. Auto is not less powerful than Hist. In fact, any arrow in Hist can be converted to Auto, and vice-versa. Similarly, Auto forms a monad in the same way Hist does. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Probably type checker error.
GHC 6.12 introduces MonoLocalBinds, which disables polymorphic values in let statements. Your original code works for me if I use -XNoMonoLocalBinds -XNoMonomorphismRestriction. On Mon, Jun 20, 2011 at 9:02 AM, Serguey Zefirov sergu...@gmail.com wrote: The fact is that (Num a) context works and (ToWires a, Num a) context doesn't. At least in 6.12.1. This still looks to me like a bug. 2011/6/19 Miguel Mitrofanov miguelim...@yandex.ru: Seems like let-generalization is at work here. Types of all values in the where section are inferred basically as if they are declared at the top level. Therefore, inheritance fails without NoMonomorphismRestriction. There is a proposal (from Big Simon) to remove let-generalization: http://research.microsoft.com/en-us/um/people/simonpj/papers/constraints/let-gen.pdf On 19 Jun 2011, at 18:26, Serguey Zefirov wrote: Right now I write a quite heavy transformation of Haskell source code and found some strange behaviour of typechecker. Some prerequisites: -- dummy class. My own class is much bigger, but I -- could reproduce that behaviour with that class. class ToWires a -- a type with phantom type arguments. data E ins outs = E -- a function that relates E and its inputs. projectInsType :: E ins outs - ins projectInsType = error projectInsType gets evaluated. -- register function. register :: a - a - a register def a = def -- a simple addition. add2 :: (ToWires a, Num a) = (a,a) - a add2 (a,b) = a+b First I have a function: func :: (ToWires a, Num a) = Maybe a - a func mbA = currentSum where x = case mbA of Just a - a Nothing - 0 nextSum = add2 (x,currentSum) currentSum = register 0 nextSum It typechecks and works just fine after some transformation. The transformation I work on transform code into something like that: func_E :: (ToWires a, Num a) = E (Maybe a) a func_E = r where r = E -- here we relate mbA and r. mbA = projectInsType r x = case mbA of Just a - a Nothing - 0 nextSum = add2 (x,currentSum) currentSum = register 0 nextSum Note the absence of input of func in transformed func_E. I relate mbA with it's proper type using binding mbA = projectInsType r. Then suddently ghc loses all of the context associated with mbA. And find type error at the calling of add2. If I drop ToWires from contexts of func_E and add2 types, all works fine. If I change add2 to simple addition (x + currentSum), all works fine. Full source code is in attachment. I found it using ghc 6.12.1. I asked colleagues, they told me that the same error manifests itself in ghc 7.0.3. Should I fill a bug report or maybe I misunderstood something? a.hs___ 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 -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Constraints on Data Constructors
On Wed, Jun 8, 2011 at 3:15 PM, Malcolm Wallace malcolm.wall...@me.com wrote: data Bar f a = Foo f = Bar {bar :: f a} The class context on the data constructor buys you nothing extra in terms of expressivity in the language. All it does is force you to repeat the context on every function that uses the datatype. For this reason, the language committee has decided that the feature will be removed in the next revision of Haskell. You're thinking of a context on the type constructor, i.e., data Foo f = Bar f a = Bar { bar :: f a } The reason the original code does not work is that the constructor only adds Foo f to the class context during pattern matching. So, for example, this works: baz :: Bar f a - a - f a -- n.b., no Foo context baz (Bar _) = foo But the code in the original post is trying to create a value of type Bar f a, so the context is needed. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ArrowLoop and streamprocessors
On Thu, Mar 31, 2011 at 11:01 AM, Matthew Steele mdste...@alum.mit.edu wrote: On Mar 30, 2011, at 5:29 PM, Mathijs Kwik wrote: So loop really doesn't seem to help here, but I couldn't find another way either to feed outputs back into the system. What I need is: Either A B ~ Either C B - A ~ C Does such a thing exist? Based on your description, it sounds to me like you want a loop such that if a B is generated at the end, you send it back to the start and execute your arrow a second time. Is that in fact what you intended? However, the docs for ArrowLoop's loop function make it clear that it executes the arrow only once: http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/Control-Arrow.html#v:loop If your arrows are instances of ArrowApply, I believe you could use app to implement the combinator you want. If your arrow's combinators are lazy enough, you can do something like this: foo :: ArrowChoice (~) = (Either a b ~ Either c b) - (a ~ c) foo f = (id ||| bar) . f . arr Left where bar = (id ||| bar) . f . arr Right But maybe Arrow isn't the proper abstraction. Perhaps something more similar to Fudgets is appropriate? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Defining subtraction for naturals
On Thu, Mar 17, 2011 at 2:35 PM, wren ng thornton w...@freegeek.org wrote: Another question on particulars. When dealing with natural numbers, we run into the problem of defining subtraction. There are a few reasonable definitions: (1) If the result would drop below zero then throw an overflow error; (2) Use saturating subtraction, i.e. if the result would drop below zero then return zero; (3) Use type hackery to disallow performing subtraction when the result would drop below zero, e.g. by requiring a proof that the left argument is not less than the right. Dependently typed languages tend to use the second definition because it gives a pure total function (unlike the first) and because it's less obnoxious to use than the third. In Haskell the third would be even more obnoxious. So my question is, mathematically speaking, is there any reason to prefer the second option over the first or third? Purity aside, I mean; do the natural numbers with saturating subtraction form any interesting mathematical object, or is it just what we're stuck with? In What About the Natural Numbers, Colin Runciman argues for definition 2, but he doesn't provide much analysis beyond noting that it gives you length (drop n xs) = length xs - n He also argues for setting x / 0 = x for strict naturals or x / 0 = infinity for lazy naturals. There are some use cases for both in the paper. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Generalizing catMaybes
On Sat, Jan 8, 2011 at 12:05 PM, Conor McBride co...@strictlypositive.org wrote: On 8 Jan 2011, at 15:27, Henning Thielemann wrote: On Sat, 8 Jan 2011, Conor McBride wrote: On 8 Jan 2011, at 11:14, Henning Thielemann wrote: For me, the solutions of Dave Menendez make most sense: Generalize Maybe to Foldable and List to MonadPlus. What has it to do with monads? There's no bind in sight. I see a '=' in front of each of his expressions. That'll teach me to wake up first. Sorry. If you have some m (f x), and you make an (m x) from each inner x, then you do need something joiny. Of course, there is an alternative generalisation. [] and Maybe are both Foldable, hence so is their composition. There's got to be a thing of type collapse :: (Foldable f, Alternative a) = f x - a x which would do the job. Something along these lines, I'd imagine. collapse = foldr (\a b - pure a | b) empty Then, to get catMaybes you could either use composition, or just write it out manually: doubleCollapse = foldr (\a b - foldr (\c d - pure c | d) empty a | b) empty :: (Foldable f, Foldable g, Alternative h) = f (g a) - h a For the generalized catMaybes, f ~ h. Of course, anything which is both foldable and alternative certainly has a function with the type of join. Right, that's doubleCollapse when f ~ g ~ h. Alternative and Foldable are both specified rather loosely, so it's not clear how closely doubleCollapse approximates join. In particular, are | and empty expected to form a monoid? If not, we could define a list- or stream-like structure that uses alternation instead of appending for (|). That would not behave at all like join. Right now, I suspect any type which has with a monoidal structure, pure, and a fold that respects the monoid has a join. That is, if you have: foldMap f mempty = mempty foldMap f (a `mappend` b) = foldMap f a `mappend` foldMap f b then when f = pure you can take a structure apart and put it back together piece by piece. I think that's enough to get you join. Naturally, if you also have pure and fmap, you also have a monad. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Generalizing catMaybes
On Sat, Jan 8, 2011 at 5:07 PM, Tony Morris tonymor...@gmail.com wrote: Thanks guys for all the solutions. A slight correction below. On 09/01/11 03:54, David Menendez wrote: Naturally, if you also have pure and fmap, you also have a monad. You have a pointed functor but not necessarily a monad. You perhaps missed the word also. If you have join, and you also have pure and fmap, then you have a monad. That's admittedly a little fuzzy about what it means to have join, since the laws join must satisfy are defined in terms of fmap and pure. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Set monad
On Sat, Jan 8, 2011 at 4:53 PM, Lennart Augustsson lenn...@augustsson.net wrote: It so happens that you can make a set data type that is a Monad, but it's not exactly the best possible sets. There's also the infinite search monad, which allows you to search infinite sets in finite time, provided your queries meet some termination criteria. http://math.andrej.com/2008/11/21/a-haskell-monad-for-infinite-search-in-finite-time/ http://hackage.haskell.org/package/infinite-search -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Generalizing catMaybes
On Fri, Jan 7, 2011 at 9:56 PM, Tony Morris tonymor...@gmail.com wrote: I am wondering if it possible to generalise catMaybes: (Something f, SomethingElse t) = t (f a) - t a I have being doing some gymnastics with Traversable and Foldable and a couple of other things from category-extras to no avail. Perhaps someone else's brain is molded into an appropriate shape to reveal an answer! This gets you part of the way there: (= maybe mzero return) :: (MonadPlus m) = m (Maybe a) - m a I'm not sure what the SomethingElse should look like. One possibility would be Foldable. (= Data.Foldable.foldr (mplus . return) mzero) :: (MonadPlus m, Foldable t) = m (t a) - m a I have a MonadPlus-to-Monoid wrapper I call MSum, so I could also write it, (= getMSum . foldMap (MSum . return)) :: (MonadPlus m, Foldable t) = m (t a) - m a -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Intro to monad transformers
On Sun, Dec 26, 2010 at 2:00 PM, michael rice nowg...@yahoo.com wrote: instance Monad m = MonadPlus (MaybeT m) where mzero = MaybeT $ return Nothing mplus x y = MaybeT $ do maybe_value - runMaybeT x case maybe_value of Nothing- runMaybeT y Just value - runMaybeT x The last line is wrong. It should be, Just value - return value. But that doesn't cause the problem. instance Show (MaybeT m a) This is never valid. You've defined show, shows, and showsPrec in terms of each other, creating unbounded recursion. Delete it. *Main askPassword Loading package transformers-0.2.2.0 ... linking ... done. *** Exception: stack overflow This triggers the unbounded recursion, when it tries to show askPassword. Note that there is no way to show IO values, so there's no way to show MaybeT IO values. Instead, use runMaybeT askPassword -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type class design
On Tue, Dec 21, 2010 at 4:30 AM, Jean-Marie Gaillourdet j...@gaillourdet.net wrote: Hi, sorry for answering to such an old thread. David Menendez d...@zednenem.com writes: On Fri, Oct 29, 2010 at 8:33 AM, Tillmann Rendel ren...@informatik.uni-marburg.de wrote: Hi, Uwe Schmidt wrote: In the standard Haskell classes we can find both cases, even within a single class. Eq with (==) as f and (/=) as g belongs to the 1. case Note that the case of (==) and (/=) is slightly different, because not only can (/=) be defined in terms (==), but also the other way around. The default definitions of (==) and (/=) are mutually recursive, and trivially nonterminating. This leaves the choice to the instance writer to either implement (==) or (/=). Or, for performance reasons, both. While I understand the argument in general, I've never understood why it applies to Eq. Are there any types where it is preferable to define (/=) instead of (==)? Yes for infinite data structures. How so? For an infinite structure, x == y will return False or not return and x /= y will return True or not return. We still have x /= y = not (x == y) and I don't see any reason why one would prefer to define (/=) instead of (==). -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Directed Name Resolution
On Thu, Nov 11, 2010 at 8:16 PM, John Lask jvl...@hotmail.com wrote: consider length ... I have records with the attribute length, length can be given as an Int, Double, Float or maybe as a constructed type Length, length's use as a record selector would also clash with List.length. All these have the same denotation. should I then seporate into int_length, float_length, or use rec1_length, rec2_length etc etc... class Lengthy a where type LengthType a length :: a - LengthType a This extends easily to lenses if you want setters. This is easily handled in C, Pascal, PL/1, Cobol why not in Haskell ? By this argument, Haskell should provide global mutable state and allow side-effects universally. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re: [Haskell-cafe] Type Directed Name Resolution
On Thu, Nov 11, 2010 at 10:00 PM, John Lask jvl...@hotmail.com wrote: On Thu, Nov 11, 2010 at 8:16 PM, John Laskjvl...@hotmail.com wrote: consider length ... I have records with the attribute length, length can be given as an Int, Double, Float or maybe as a constructed type Length, length's use as a record selector would also clash with List.length. All these have the same denotation. should I then seporate into int_length, float_length, or use rec1_length, rec2_length etc etc... class Lengthy a where type LengthType a length :: a - LengthType a This extends easily to lenses if you want setters. to make use of the class Lengthy I still need to define record selectors with different names, which is exactly the point I am making... ie data Record = RecLen { rec_length :: ... } instance Lengthy Record where length = rec_length Or, data Record = RecLen Int ... instance Lengthy Record where type LengthType Record = Int length (Record l _ _ ...) = l But yes, this is irritating boilerplate. A more-powerful record system is clearly preferable. The point is that languages are often constructed with a purpose in mind, at which they tend to be particularly good. Haskell has traditionally been a test bed for type system innovation, which is why we all like it so much. Which is why I'm opposed to TDNR. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type class design
On Fri, Oct 29, 2010 at 8:33 AM, Tillmann Rendel ren...@informatik.uni-marburg.de wrote: Hi, Uwe Schmidt wrote: In the standard Haskell classes we can find both cases, even within a single class. Eq with (==) as f and (/=) as g belongs to the 1. case Note that the case of (==) and (/=) is slightly different, because not only can (/=) be defined in terms (==), but also the other way around. The default definitions of (==) and (/=) are mutually recursive, and trivially nonterminating. This leaves the choice to the instance writer to either implement (==) or (/=). Or, for performance reasons, both. While I understand the argument in general, I've never understood why it applies to Eq. Are there any types where it is preferable to define (/=) instead of (==)? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Thu, Sep 9, 2010 at 11:33 PM, wren ng thornton w...@freegeek.org wrote: On 9/9/10 1:04 AM, David Menendez wrote: Fascinating. I figured there might be a counter-example involving seq, but this is pretty subtle. In particular, would it be fair to say that in Haskell-without-seq, E (f a) a and E (f a) (f a) are indistinguishable? Yes, I think that without polymorphic seq (or within a strict language) they are observationally equivalent. But, observational equivalence is not the same as equality. And the category theoretic laws really do mean equality. To pick an example: consider the case where 'a' is an enormous data structure and (f a) returns some small value. Even though (E (f a) a) and (E (f a) (f a)) are observationally equivalent within Haskell, they're still observationally distinct from outside of the language because they have very different memory profiles. (We may need to make E strict in the second argument, or NOINLINE impure, in order to guarantee this behavior.) Thus, the equality still fails, though this may go undetected for a long time until someone notices the memory leak. It seems like you could use a similar argument to show that fmap id /= id. Specifically, xs and map id xs are equivalent lists, but they occupy different locations in memory. By replacing xs with map id xs, you can come arbitrarily close to doubling a program's memory requirements. (You can also use pointer comparison to distinguish them, but I assume that doesn't count.) What about Set.map? We have forall s. Set.map id s == s, but the actual structure may not be identical. In principle, there's no way to observe the difference, but in practice you can do it by breaking the precondition on foldMap. Does that mean we can't consider Set.Set/Set.map a functor over the subcategory of ordered Haskell types? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Wed, Sep 8, 2010 at 11:17 PM, wren ng thornton w...@freegeek.org wrote: On 9/7/10 4:21 AM, Daniel Fischer wrote: On Tuesday 07 September 2010 05:22:55, David Menendez wrote: In fact, I think *every* appropriately-typed function satisfies that law. Does anyone know of a counter-example? -- | Multiply the *Hask* category by its number of objects. data E a where E :: a - b - E a -- | Maintain all the morphisms of *Hask* in each *E*-copy of -- it, but keep the tag for which *E*-copy we were in. instance Functor E where fmap f (E a b) = E (f a) b snip -- | The object part of a functor to enter *E* along the diagonal. impure :: a - E a impure a = E a a -- | Proof that impure is not p...@e fmap f (impure a) == fmap f (E a a) == E (f a) a /= E (f a) (f a) == impure (f a) And yet, impure has the correct type. Fascinating. I figured there might be a counter-example involving seq, but this is pretty subtle. In particular, would it be fair to say that in Haskell-without-seq, E (f a) a and E (f a) (f a) are indistinguishable? Functors like this happen to be helpful too, not just as oddities. They're functors for tracking the evolution of a value through a computation (e.g., tracking the initial value passed to a function). In this example, the existential tag is restricted by observational equivalence to only allow us to distinguish bottom from non-bottom initial values. But we can add context constraints on the data constructor in order to extract more information; at the cost of restricting impure to only working for types in those classes. ...at which point, it no longer has the same type as pure. But your point is taken. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Mon, Sep 6, 2010 at 7:51 AM, John Lato jwl...@gmail.com wrote: On Sun, Sep 5, 2010 at 7:18 PM, David Menendez d...@zednenem.com wrote: On Sun, Sep 5, 2010 at 8:40 AM, John Lato jwl...@gmail.com wrote: On Sat, Sep 4, 2010 at 12:34 PM, David Menendez d...@zednenem.com wrote: On Fri, Sep 3, 2010 at 8:23 AM, John Lato jwl...@gmail.com wrote: +1 for using the proper constraints, and especially for bringing over Pointed (and anything else that applies). What's the argument for Pointed? Are there many types which are instances of Pointed but not Applicative? Are there many algorithms which require Pointed but not Applicative? Having Pointed is categorically the right thing to do, which is why I argue for its inclusion. Why is it categorically the right thing to do? Because it's the proper abstraction underlying Applicative and Monad, as far as I understand category theory. What makes it the proper abstraction? Applicative Functors have three parts: the functor, pure, and *, along with some equations they need to satisfy. We know Functor by itself is useful, but what makes Functor+pure better than Functor+* or pure+* or any other subset? The fact that it has a name doesn't make it useful for programming; category theory has names for all sorts of things that don't come up very often. For that matter, can you even describe what pure is intended to do without reference to * or join? You can say that it's a natural transformation from Id to f, but so is \x - [x,x]. You can say it contains one copy of the argument, but that doesn't work for the Const functor or the infinite stream functor, among others. I notice no one has given any algorithms that operate on arbitrary pointed functors. When Conor McBride was promoting the use of Applicative (then called Idiom), he provided several instances and algorithms showing that it was a useful generalization of Monad, and it still took several years and a few papers[1] before Applicative found its way into the standard library. In other words, we didn't add Applicative and then discover Traversable later. Traversable was a big part of the argument for why Applicative is useful. I take this in favor of my point. Applicative wasn't considered useful, so it wasn't included. Then Conor McBride shows that it is useful, but at that point it was too late and now we're stuck with pure, return, ap, liftA2, liftM2, etc. I think that has more to do with Haskell 98 compatibility. We broke Category out of Arrow not too long ago. Furthermore, you didn't address my point: Applicative is *useful*. We have algorithms that are parameterized by arbitrary applicative functors. We have multiple examples of useful non-monad applicative functors. What are pointed functors good for? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Operator precedence
On Mon, Sep 6, 2010 at 1:37 PM, michael rice nowg...@yahoo.com wrote: A concrete library? I'm playing around with Data.Bits. It has .. and .|. which I assume are functions (rather than operators) because I don't see and infix statement for them. Correct? .|. and .. are operators because they are made from symbol characters. Operators default to infixl 9 unless specified otherwise, so no infix declaration is needed. However, Data.Bits does have infix declarations for .. and .|. : infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR` infixl 7 .. infixl 6 `xor` infixl 5 .|. If you want to check the fixity of an operator, use :info in GHCi. Prelude Data.Bits :i .|. class (Num a) = Bits a where ... (.|.) :: a - a - a ... -- Defined in Data.Bits infixl 5 .|. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Operator precedence
On Mon, Sep 6, 2010 at 2:21 PM, Daniel Díaz danield...@asofilak.es wrote: El Lun, 6 de Septiembre de 2010, 7:50 pm, David Menendez escribió: Operators default to infixl 9 unless specified otherwise, so no infix declaration is needed. Why there is a default infix? Why it is 9? That's what the Haskell Report says: Any operator lacking a fixity declaration is assumed to be infixl 9 (section 4.4.2). Any function with at least two arguments can be used as an operator, so there has to be a default. Presumably, infixl 9 was considered the least surprising. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Mon, Sep 6, 2010 at 10:22 PM, wren ng thornton w...@freegeek.org wrote: On 9/6/10 1:33 PM, David Menendez wrote: For that matter, can you even describe what pure is intended to do without reference to* or join? As already stated: fmap f . pure = pure . f That's pretty general. For lists, the functions having that property include const [], \x - [x,x], and repeat. In fact, I think *every* appropriately-typed function satisfies that law. Does anyone know of a counter-example? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Sun, Sep 5, 2010 at 8:40 AM, John Lato jwl...@gmail.com wrote: On Sat, Sep 4, 2010 at 12:34 PM, David Menendez d...@zednenem.com wrote: On Fri, Sep 3, 2010 at 8:23 AM, John Lato jwl...@gmail.com wrote: +1 for using the proper constraints, and especially for bringing over Pointed (and anything else that applies). What's the argument for Pointed? Are there many types which are instances of Pointed but not Applicative? Are there many algorithms which require Pointed but not Applicative? Having Pointed is categorically the right thing to do, which is why I argue for its inclusion. Why is it categorically the right thing to do? When Conor McBride was promoting the use of Applicative (then called Idiom), he provided several instances and algorithms showing that it was a useful generalization of Monad, and it still took several years and a few papers[1] before Applicative found its way into the standard library. In other words, we didn't add Applicative and then discover Traversable later. Traversable was a big part of the argument for why Applicative is useful. [1] Idioms: applicative programming with effects http://www.cs.nott.ac.uk/~ctm/Idiom.pdf Also, I think it would be prudent to avoid a situation with the possibility of turning into a rehash of the Functor/Applicative/Monad mess. Granted, but let's not rush blindly in the opposite direction. Are there any good reasons for not including it? Just because we don't have a use now doesn't mean it might not be useful in the future. This is an argument for putting every member of the container API into its own independent class. Why make things more complicated for little or no benefit? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Sun, Sep 5, 2010 at 8:47 AM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: I _can_ think of a data type that could conceivably be an instance of Pointed but not Applicative: a BloomFilter (though there's not really any point in having a BloomFilter with only one value that I can see, but maybe someone can since there's the singletonB function). Do Bloom filters have a Functor instance? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Haddock version 2.8.0
On Sat, Sep 4, 2010 at 11:07 AM, John Millikin jmilli...@gmail.com wrote: On Fri, Sep 3, 2010 at 23:02, David Menendez d...@zednenem.com wrote: Yes, using foreign namespaces is one of the things recommended against when serving XHTML as text/html. This says nothing about documents following the recommendations in Appendix C. I'm not debating that it's *possible* to serve HTML with an XHTML mimetype and still see something rendered to the screen. Hundreds of thousands of sites do so every day. But to call this XHTML is absurd. I agree, if by absurd you mean consistent with the letter and spirit of the XHTML recommendation. Content served as text/html is not XHTML, any more than content served as text/plain or image/jpg is. Metadata does not determine data. If I write created: 1810 on the Haskell Report, that does not make it 200 years old. If I seve a JPEG image as text/html, it's still a JPEG image. We just wouldn't expect a browser to render it correctly, because the metadata is wrong. Appendix C describes a subset of XHTML, such that a document in conformance with it may be interpreted usefully as HTML by most web browsers. The document is still XHTML, and may be given to XHTML or generic XML tools without difficulty. You seem to be under the common misconception that XHTML is merely an alternative encoding of HTML. HTML and XHTML are not encodings of anything. They are markup languages defined using SGML and the XML subset of SGML. There are multiple HTML definitions of varying popularity, and the fact that we can pass some XHTML documents to a web browser expecting HTML and get acceptable results is consistent with the fact that we can pass HTML 3.0 (never implemented by any popular browser) with minimal loss. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Restricted type classes
On Fri, Sep 3, 2010 at 8:23 AM, John Lato jwl...@gmail.com wrote: Do you have a kind * implementation of Foldable? I'd be interested in seeing it, because I was unable to create a usable implementation (based upon the RMonad scheme) on my last attempt. I always figured it would look something like: class Foldable f where type Elem f :: * foldMap :: Monoid m = (Elem f - m) - f - m with the usual definitions for foldr, foldl, etc. +1 for using the proper constraints, and especially for bringing over Pointed (and anything else that applies). What's the argument for Pointed? Are there many types which are instances of Pointed but not Applicative? Are there many algorithms which require Pointed but not Applicative? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On to applicative
On Sat, Sep 4, 2010 at 2:06 PM, michael rice nowg...@yahoo.com wrote: The two myAction functions below seem to be equivalent and, for this small case, show an interesting economy of code, but being far from a Haskell expert, I have to ask, is the first function as small (code wise) as it could be? Michael import Control.Applicative data Color = Red | Blue | Green | Yellow | Orange | Brown | Black | White deriving (Show, Read, Eq, Enum, Ord, Bounded) -- myAction :: IO Color -- myAction = getLine --= \str - return (read str :: Color) First, you don't need the type annotation here. Haskell will infer it from the annotation on myAction. (You also don't need the type on myAction, but that's not important now.) myAction = getLine = \str - return (read str) Second, you have the pattern \x - f (g x), so you can replace the lambda with function composition. myAction = getLine = return . read Third, there is a standard function liftM, defined in Control.Monad, where liftM f m = m = return . f, so myAction = liftM read getLine Finally, we expect an instance of Monad to also be an instance of Functor, with fmap = liftM, and we also have f $ m = fmap f m, so myAction :: IO Color myAction = read $ getLine -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Haddock version 2.8.0
On Fri, Sep 3, 2010 at 12:40 AM, John Millikin jmilli...@gmail.com wrote: Haddock is generating files with an .html extension, which causes webservers to serve it using text/html, the incorrect MIME-type. Secton 5.1 of the XHTML recommendation states: XHTML Documents which follow the guidelines set forth in Appendix C, 'HTML Compatibility Guidelines' may be labeled with the Internet Media Type 'text/html' [RFC2854], as they are compatible with most HTML browsers. http://www.w3.org/TR/xhtml1/#media I haven't checked Haddock's conformance with Appendix C, but it is incorrect to say that XHTML cannot be served as text/html. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On to applicative
On Thu, Sep 2, 2010 at 10:45 AM, michael rice nowg...@yahoo.com wrote: Can you think of a situation for \x - f x or \x y z - x + ord y - head z that would require x (y z) to have their type(s) declared (ala Pascal), or is it always inferred by what appears to the right of -? I think Haskell 98 can always infer the type of an anonymous function. There are some extensions involving more advanced types that can't be inferred, but you don't need to worry about them yet. I guess what I'm asking is can an anonymous function be given a type signature? Sure. Just write (\x - x + 1) :: Int - Int. (The parentheses are important. Without them, the type signature is given to the function body.) I don't think I've ever needed to give a type for an anonymous function, though. Generally, the context where the function is being used is sufficient. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] On to applicative
On Thu, Sep 2, 2010 at 9:16 PM, michael rice nowg...@yahoo.com wrote: This may be a dumb question, but here goes. Types Maybe, Either, List, are types and also instances of Functor (and Monad). Assuming (-) is also a type, where can I find its type definition? (-) is a built-in type. You could say its definition is in the Haskell Report. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Arrow transformers: how to make them wright?
On Tue, Aug 31, 2010 at 2:07 PM, Permjacov Evgeniy permea...@gmail.com wrote: A Control.Arrow in base package introduces an arrow type, and ghc have good support for arrow notation. Many things, avaible in monads, are avaible in arrows as well. There is an arrows package, that introduces some arrow classes : state, reader, writer and so on. However, it does not introduce systematic lifting of arrow classes operations. Are you referring to the arrows package at http://hackage.haskell.org/package/arrows? If so, what do you mean by systematic lifting, because it does lift operations through the transformers where possible. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: String vs ByteString
On Fri, Aug 13, 2010 at 10:43 AM, Johan Tibell johan.tib...@gmail.com wrote: Here's a rule of thumb: If you have binary data, use Data.ByteString. If you have text, use Data.Text. Those libraries have benchmarks and have been well tuned by experienced Haskelleres and should be the fastest and most memory compact in most cases. There are still a few cases where String beats Text but they are being worked on as we speak. It's a good rule, but I don't know how helpful it is to someone doing XML processing. From what I can tell, the only XML library that uses Data.Text is libxml-sax, although tagsoup can probably be easily extended to use it. HXT, HaXml, and xml all use [Char] internally. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Yet another monad transformer or silly usage of Either?
2010/7/25 Eugeny N Dzhurinsky b...@redwerk.com: Hello, everybody! I am trying to develop some sort of library, which supposed to sign into a WEB service, then perform some requests with it. Initially I designed methods in the following way data DServError = InvalidCredentials | InvalidRequest | ... newtype Result a = Result { getOpResult :: Either DServError a } data DSession = Session { ... } data DLoginResponse = LoginResponse { currentSession :: DSession, ... } login :: String - String - IO ( Result LoginResponse ) servRequest1 :: DSession - ParamType1 - ParamType2 - ... - IO ( Result DServResponse ) Now I want to be able of doing something like authenticatedReq = do loginResponse - login username password let session = currentSession loginResponse servRequest1 session ... ... ... servRequest2 session ... ... ... ... so if login succeeds - I will be able to extract Right data from the Either response ( with explicit or implicit usage of getOpResult), if any of operations within do block will fail with DServError - then an error should be reported. I think the solution for this may be using Control.Exception and it's try/catch? That would work. If all of your operations require IO, you may as well use IO for exceptions. It really depends on how explicit you want to be about the varieties of exceptions your code may throw. The documentation for Control.Exception has a pretty good explanation of how to define instances for Exception. e.g., data DServError = InvalidCredentials | ... deriving (Show, Typeable) instance Exception DServError DServError login :: String - String - IO LoginResponse servRequest1 :: DSession - ParamType1 - ... - IO DServResponse It may be a better choice to make each exception its own type, and possibly create a sub-heirarchy. E.g., data DServError = forall a. (Exception a) = DServError a deriving (Typeable) instance Show DServError where show (DServError a) = show a dServErrorToException :: Exception a = a - SomeException dServErrorToException = toException . DServError dServErrorFromException :: Exception a = SomeException - Maybe a dServErrorFromException x = fromException x = \(DServError a) - cast a data InvalidCredentials deriving (Show, Typeable) instance Exeption InvalidCredentials where toException = dServErrorToException fromException = dServErrorFromException data InvalidRequest deriving (Show, Typeable) instance Exeption InvalidRequest where toException = dServErrorToException fromException = dServErrorFromException etc. This allows you to write m `catch` \(e :: DServError) - ... and m `catch` \InvalidCredentials - ... without worrying about pattern-match errors. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Design for 2010.2.x series Haskell Platform site
On Sat, Jul 17, 2010 at 2:10 PM, Don Stewart d...@galois.com wrote: andrewcoppin: Don Stewart wrote: allbery: like to repeat one request: Please, please, please make it easier to - Download older versions of HP. - Find out which HP release contains what. - Figure out what the difference between release X and release Y is. +1 I'd consider this mandatory. It's amazing how many projects apparently *don't*. We can certainly continue to link to old versions, to the old contents.html and the changelogs, as is currently planned. And unlike previous releases, this one seems to have a changelog. (It's nontrivial comparing two Cabal files trying to figure out what changed!) Actually, it just got trivial: $ diffcabal old-platform.cabal haskell-platform.cabal Cabal 1.8.0.2 - 1.8.0.6 QuickCheck 2.1.0.3 - 2.1.1.1 [etc.] Okay, so where do I go to find out the difference between, say, QuickCheck 2.1.0.3 and 2.1.1.1? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Actually loading a Cabal package in GHCi
On Sun, Jul 11, 2010 at 3:25 PM, d...@patriot.net wrote: Prelude Haskore :l Haskore no location info: module `Haskore' is a package module Failed, modules loaded: none. You need to use :m here. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] checking types with type families
On Sat, Jul 3, 2010 at 3:32 AM, Kevin Quick qu...@sparq.org wrote: On Wed, 23 Jun 2010 00:14:03 -0700, Simon Peyton-Jones simo...@microsoft.com wrote: I'm interested in situations where you think fundeps work and type families don't. Reason: no one knows how to make fundeps work cleanly with local type constraints (such as GADTs). Simon, I have run into a case where fundeps+MPTC seems to allow a more generalized instance declaration than type families. The fundep+MPTC case: {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances, UndecidableInstances #-} class C a b c | a - b, a - c where op :: a - b - c instance C Bool a a where op _ = id main = putStrLn $ op True done In this case, I've (arbitrarily) chosen the Bool instance to be a no-op and pass through the types. Because the dependent types are part of the declaration header I can use type variables for them. That's really weird. In particular, I can add this line to your code without problems: foo = putStrLn $ if op True True then done else . but GHC complains about this one: bar = putStrLn $ if op True True then op True done else . fd.hs:14:0: Couldn't match expected type `Bool' against inferred type `[Char]' When using functional dependencies to combine C Bool [Char] String, arising from a use of `op' at fd.hs:14:38-51 C Bool Bool Bool, arising from a use of `op' at fd.hs:14:20-31 When generalising the type(s) for `bar' On the other hand, this is fine, but only with a type signature: baz :: a - a baz = op True I don't think this is an intended feature of functional dependencies. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell sees into abstract data types
On Sat, Jul 3, 2010 at 7:20 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: Serguey Zefirov sergu...@gmail.com writes: I cannot directly create my own class instances for them because of that. But I found that I can write Template Haskell code that could do that - those data types could be reified just fine. snip This is somewhat strange situation. Was it a design decision? The reason that they are exported abstractly is so that you don't see the internals of the data structure, because 1) you don't need to, and 2) to stop you from doing anything stupid with them. I was talking about successful reification of abstract data types. That way I can do anything stupid with them. Why do you want to? I believe the point is that Template Haskell can see the internal structure of a type even when the constructors are not exported. The question is whether or not that is intentional. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Associated types
On Thu, Jul 1, 2010 at 2:09 PM, Andrew Coppin andrewcop...@btinternet.com wrote: Consider the following: class Path p where ... class Path p = CompletePath p where ... class Path p = IncompletePath p where type CompletedPath p :: * Obviously, the idea is that CompletedPath Foo (where Foo is an IncompletePath) should yield some type which is a CompletePath. However, the source code does not actually state this, so GHC (rightly) complains that it was unable to deduce this constraint from the actual code written. Is it possible to state this constraint? If so, how? (And if not, the answer, presumably, is to fundamentally redesign the whole thing...) Something like this should work: class (Path p, CompletePath (CompletedPath p)) = IncompletePath p where type CompletedPath p :: * -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Associated types
On Thu, Jul 1, 2010 at 2:35 PM, Christopher Lane Hinson l...@downstairspeople.org wrote: On Thu, 1 Jul 2010, Christopher Lane Hinson wrote: Something like this should work: class (Path p, CompletePath (CompletedPath p)) = IncompletePath p where type CompletedPath p :: * AIUI, this isn't implemented yet. You'll have to place the constraint on each involved function. Friendly, --Lane I would have sworn I tested this in 6.12.x, but I'm wrong. It works. Isn't there something left unimplemented that I am thinking of? Tell me I'm not crazy! Maybe you're thinking of equality superclasses. In another thread, this example came up: | class (DerivedOf a ~ derived) = Typecheck a derived where which doesn't work yet, but should work in 6.14. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: The mother of all functors/monads/categories
On Sun, Jun 27, 2010 at 1:26 PM, Sebastian Fischer s...@informatik.uni-kiel.de wrote: Hi Max, very interesting observations! By the way, you can use this stuff to solve the restricted monad problem (e.g. make Set an instance of Monad). This is not that useful until we find out what the mother of all MonadPlus is, though, because we really need a MonadPlus Set instance. I'm not sure whether this is TMOA MonadPlus, but here is a set monad with MonadPlus instance (code below). Any continuation monad can be made an instance of MonadPlus if the final value is a monoid. But whether that serves your purposes or not depends on what specific properties you want mplus to have. It's also worth asking why you might prefer the set monad to the list monad. It has some nice properties (it's commutative and idempotent), but you can get that by using the list monad internally and only allowing observation of the values after converting to Set. There's also the efficiency angle. In the list monad, this expression: return x `mplus` return x = f will calculate (f x) twice. In principle, the set monad can avoid this, but in the continuation-based implementation, this evaluates to \k - Set.union (f x - k) (f x - k), which is just as inefficient as the list monad. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: signficant improvements to the containers package
On Fri, Jun 25, 2010 at 12:58 AM, Ivan Miljenovic ivan.miljeno...@gmail.com wrote: On 25 June 2010 14:41, David Menendez d...@zednenem.com wrote: On Thu, Jun 24, 2010 at 3:08 AM, Ivan Miljenovic ivan.miljeno...@gmail.com wrote: As an aside, Alex Mason and I are discussing the possibility of taking advantage of AusHack *shameless plug* to write some kind of classes for the different types of containers with a hierarchy. I know about ListLike, but there doesn't seem to be any applicable classes for generic containers (i.e. the abstract API of a Set; something like ListLike would then be an extension on it) and for lookup data structures (Map k a, [(k, a)], etc.). Be sure to look into Okasaki's work on Edison. It has classes for sequences (list-like structures) and collections (sets, heaps) and associations (maps, priority queues) and a paper discussing the design decisions. Yeah, we will be. The reason this came up: Thomas Berekneyi wanted to use such classes for the rewrite of FGL, and when he discussed it on #haskell people generally indicated that edison was the best out there but was a bit long in the tooth and something like it should be re-written (though no-one seemed to volunteer... hmmm... :p). Edison could use some re-thinking; the state of the art in Haskell has advanced, and there are new classes like Data.Foldable and Data.Traversable to consider. In my mind, the big question is whether Sequence and Assoc should be constructor classes or use type families/fundeps. I lean towards the former, but it means that things like ByteSting can't be instances of Sequence. For example: it's a little weird that edison re-exports Data.Set and uses it for the instance with a type alias (same with map, Seq, etc.) rather than just using Data.Set itself. I believe that's so the implementations export a common interface. If you're in a situation where you want to use a specific implementation, Edison is designed so that you can import just the implementation module and avoid the overhead of the class system while still making it easy to switch implementations in the future. I also find the structuralInvariant and instanceName fields to be a little odd, I believe structuralInvariant is there for testing. I'm not sure what instanceName is for. It's possible Edison predates Data.Typeable, in which case instanceName might be useful for similar purposes. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Fwd: signficant improvements to the containers package
On Thu, Jun 24, 2010 at 3:08 AM, Ivan Miljenovic ivan.miljeno...@gmail.com wrote: As an aside, Alex Mason and I are discussing the possibility of taking advantage of AusHack *shameless plug* to write some kind of classes for the different types of containers with a hierarchy. I know about ListLike, but there doesn't seem to be any applicable classes for generic containers (i.e. the abstract API of a Set; something like ListLike would then be an extension on it) and for lookup data structures (Map k a, [(k, a)], etc.). Be sure to look into Okasaki's work on Edison. It has classes for sequences (list-like structures) and collections (sets, heaps) and associations (maps, priority queues) and a paper discussing the design decisions. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MonadCatchIO-transformers and ContT
On Mon, Jun 21, 2010 at 7:04 AM, Neil Brown nc...@kent.ac.uk wrote: Here's my speculation, based on glancing at the libraries involved: I believe the reason for this may be the MonadCatchIO instance for ContT: === instance MonadCatchIO m = MonadCatchIO (ContT r m) where m `catch` f = ContT $ \c - runContT m c `catch` \e - runContT (f e) c === To my eye, that code takes the continuation to run after the block, c (which in your case involves the after-action from bracket_, and then the error), and runs that inside the catch block. This causes a successful completion of bracket_ (first release), followed by the error, which triggers the catch block which then runs the final actions (second release) and rethrows the error. Does that sound possible to anyone else? Sounds possible to me. ContT does not play well with control operations from other monads. Most people would expect, e.g., lift m `catch` lift . f = lift (m `catch` f), but ContT does not have such an operation. If you really want explicit continuations and exceptions, you need a monad written specifically for that. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Different choice operations in a continuation monad
On Fri, Jun 18, 2010 at 12:44 PM, Heinrich Apfelmus apfel...@quantentunnel.de wrote: Sebastian Fischer wrote: Edward Kmett wrote: Sebastian Fischer wrote: Heinrich Apfelmus wrote: newtype CMaybe a = CMaybe (forall r. (a - Maybe r) - Maybe r) Yes, with this type `orElse` has the same type as `mplus`, which is very nice. This type is the same as Codensity Maybe using category-extras which is a 'bit bigger than Maybe'. (To see why, figure out how Codensity Reader is isomorphic to State!) This is the wiggle room you're using to get the distributive operator. I encounter the Codensity type constructor every now and then. I used it to Reinvent Haskell Backtracking, learned about implementing a state monad with a reader monad wrapped in Codensity when implementing Lazy Nondeterministic Programming and Janis Voigtländer also used it to improve the asymptotics of free monads. I wonder whether for every monad `m` and `a :: Codensity m a` getCodensity a f = getCodensity a return = f Is this true? Why (not)? It's not true. a = Codensity $ \x - Just 42 f = return . (+1) getCodensity a f = Just 42 ≠ getCodensity a return = f = Just 42 = f = Just 43 What definition are you using for Codensity? Under the definition I'm familiar with, that definition of a is invalid. newtype Codensity m a = Codensity { runCodensity :: forall b. (a - m b) - m b } Which is not to say that you can't come up with improper values of Codensity. E.g., Codensity (\k - k () k ()) \m - Codensity (\k - k () = \b - m return b) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Proposal to solve Haskell's MPTC dilemma
On Thu, May 27, 2010 at 10:39 AM, Carlos Camarao carlos.cama...@gmail.com wrote: Isaac Dupree: Your proposal appears to allow /incoherent/ instance selection. This means that an expression can be well-typed in one module, and well-typed in another module, but have different semantics in the two modules. For example (drawing from above discussion) : module C where class F a b where f :: a - b class O a where o :: a module P where import C instance F Bool Bool where f = not instance O Bool where o = True k :: Bool k = f o module Q where import C instance F Int Bool where f = even instance O Int where o = 0 k :: Bool k = f o module Main where import P import Q -- (here, all four instances are in scope) main = do { print P.k ; print Q.k } -- should result, according to your proposal, in -- False -- True -- , am I correct? If qualified importation of k from both P and from Q was specified, we would have two *distinct* terms, P.k and Q.k. I think Isaac's point is that P.k and Q.k have the same definition (f o). If they don't produce the same value, then referential transparency is lost. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proposal to solve Haskell's MPTC dilemma
On Fri, May 21, 2010 at 3:56 AM, Max Bolingbroke batterseapo...@hotmail.com wrote: On 21 May 2010 01:58, Carlos Camarao carlos.cama...@gmail.com wrote: But this type-correct program would become not typeable if instances such as the ones referred to before (by Daniel Fischer) I was thinking this through, and the situation is more complex than I had thought. It seems that single param type classes enjoy a nice property: * Adding an instance to the module defining the class cannot conflict with any non-orphan instance defined elsewhere * Adding an instance for a type for a class *to the module defining that type* cannot conflict with any non-orphan instance defined elsewhere This is only true in the absence of recursive imports. Otherwise, those points imply that I can put one instance in the module defining the type and another in the module defining the class without conflict. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FW: Why does this Ord-class instance crash?
2010/5/21 R J rj248...@hotmail.com: Why does the following, trivial code snippet below hang GHCi when I type Scalene Failure, and what's the fix? An instance of Ord must declare compare or (=). You only defined (), so () is using the default definition. Here are the defaults: compare x y = if x == y then EQ else if x = y then LT else GT x y = case compare x y of { LT - True; _ - False } x = y = case compare x y of { GT - False; _ - True } x y = case compare x y of { GT - True; _ - False } x = y = case compare x y of { LT - False; _ - True } max x y = if x = y then y else x min x y = if x = y then x else y Note that the default definitions of (=) and compare call each other, leading to an infinite loop when both are used. Simple fix: define (=) instead of (). -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type of (= f) where f :: a - m b
On Mon, May 10, 2010 at 5:51 AM, Milind Patil milind_pa...@hotmail.com wrote: For a function f :: a - m b f = undefined I am having trouble understanding how the type of (= f) is (= f) :: m a - m b where, by definition, type of (=) is (=) :: (Monad m) = m a - (a - m b) - m b I do not see how (= f) even unifies. I mean if I code a function with the same type as (=) ie. tt :: (Monad m) = m a - (a - m b) - m b tt = undefined type of (tt f) does not infer to the same type as (= f), from ghc ... (tt f) :: (Monad ((-) b)) = (m a - b - b1) - b - b1 There seems to something special about (=) apart from its type. And whats (Monad ((-) b))? I am new to Haskell and I may have gaps in my understanding of type inference in Haskell. It's because = is a binary operator. When you partially apply a binary operator, you get a section which applies one of the two arguments. Specifically, you have: (=) = \m f - m = f (m =) = \f - m = f (= f) = \m - m = f There's more in the Haskell tutorial (section 3.2.1) http://www.haskell.org/tutorial/functions.html Or you can check the Haskell Report, section 3.5: http://www.haskell.org/onlinereport/exps.html#sections -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO (Either a Error) question
On Sat, May 8, 2010 at 1:16 AM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: David Menendez d...@zednenem.com writes: On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic Well, any time you have a do-block like this you're using failable patterns: maybeAdd :: Maybe Int - Maybe Int - Maybe Int maybeAdd mx my = do x - mx y - my return $ x + y This is true in the sense that the translation for the do syntax in the Haskell report uses fail. do { p - e; stmts } = let ok p = do { stmts } ok _ = fail ... in e = ok However, it's also true that the fails introduced by the translation of maybeAdd will never be invoked, since the two patterns are irrefutable. Huh? What about maybeAdd (Just 2) Nothing ? That does not invoke fail. Let's take a simpler example: do { x - Nothing; stmt }. This translates to let ok x = do { stmt } ok _ = fail ... in Nothing = ok By the definition of (=) for Maybe, 'ok' is never called. That is, maybeAdd would work exactly the same if the do syntax translation were changed to read: do { p - e; stmts } = e = \p - do { stmts } Wait, are you using irrefutable as it will still work if we make do blocks work the way I want? I am using irrefutable to refer to patterns which always match. From the Haskell Report, section 3.17.2: It is sometimes helpful to distinguish two kinds of patterns. Matching an irrefutable pattern is non-strict: the pattern matches even if the value to be matched is _|_. Matching a refutable pattern is strict: if the value to be matched is _|_ the match diverges. The irrefutable patterns are as follows: a variable, a wildcard, N apat where N is a constructor defined by newtype and apat is irrefutable (see Section 4.2.3), v...@apat where apat is irrefutable, or of the form ~apat (whether or not apat is irrefutable). All other patterns are refutable. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO (Either a Error) question
On Fri, May 7, 2010 at 10:26 PM, John Meacham j...@repetae.net wrote: On Fri, May 07, 2010 at 08:27:04PM -0400, Dan Doel wrote: Personally, I don't really understand why unfailable patterns were canned (they don't seem that complicated to me), so I'd vote to bring them back, and get rid of fail. But hind sight is 20/20, I suppose (or perhaps there exist cogent arguments that I haven't heard). What counts as unfailable? (x,y) probably, but what about data Foo = Foo x y If we don't allow it, we add 'magic' to tuples, which is a bad thing, if we do allow it, there are some odd consequences. adding another constructor to Foo will suddenly change the type of do notations involving it non locally. said constructor may not even be exported from the module defining Foo, its existence being an implementation detail. All in all, it is very hacky one way or another. Much more so than having 'fail' in Monad. I wonder how often people rely on the use of fail in pattern matching. Could we get by without fail or unfailable patterns? ensureCons :: MonadPlus m = [a] - m [a] ensureCons x@(_:_) = return x ensureCons _ = mzero do ... x:xs - ensureCons $ some_compuation This is more flexible than the current situation (you can easily adapt it to throw custom exceptions in ErrorT), but gets cumbersome when you're doing nested patterns. Also, it does the match twice, but presumably the optimizer can be improved to catch that if the idiom became popular. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] IO (Either a Error) question
On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: David Menendez d...@zednenem.com writes: I wonder how often people rely on the use of fail in pattern matching. Could we get by without fail or unfailable patterns? ensureCons :: MonadPlus m = [a] - m [a] ensureCons x@(_:_) = return x ensureCons _ = mzero do ... x:xs - ensureCons $ some_compuation This is more flexible than the current situation (you can easily adapt it to throw custom exceptions in ErrorT), but gets cumbersome when you're doing nested patterns. Also, it does the match twice, but presumably the optimizer can be improved to catch that if the idiom became popular. Well, any time you have a do-block like this you're using failable patterns: maybeAdd :: Maybe Int - Maybe Int - Maybe Int maybeAdd mx my = do x - mx y - my return $ x + y This is true in the sense that the translation for the do syntax in the Haskell report uses fail. do { p - e; stmts } = let ok p = do { stmts } ok _ = fail ... in e = ok However, it's also true that the fails introduced by the translation of maybeAdd will never be invoked, since the two patterns are irrefutable. That is, maybeAdd would work exactly the same if the do syntax translation were changed to read: do { p - e; stmts } = e = \p - do { stmts } This would not be the case if refutable patterns were used. viewM l = do { x:xs - return l; return (x,xs) } -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Rank-2 polymorphism and overloading
On Mon, Apr 26, 2010 at 2:55 PM, Thomas van Noort tho...@cs.ru.nl wrote: On 26-4-2010 20:12, Daniel Fischer wrote: Am Montag 26 April 2010 19:52:23 schrieb Thomas van Noort: ... Yes, y's type is more general than the type required by f, hence y is an acceptable argument for f - even z :: forall a b. a - b - Bool is. That's what I thought. I've just never seen such a notion of a more general type involving overloading before. However, it requires y to throw away the provided dictionary under the hood, which seems counter intuitive to me. Why? y doesn't need the dictionary, so it just ignores it. Sure, but y's type explicitly mentions that it doesn't want a dictionary, so why would you provide one to it? Actually, y's type doesn't say anything at all about dictionaries. That's a detail about GHC's implementation. y's type says it will accept two values of any type. f's type says it will provide two values of a type which is an instance of Eq. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proper Handling of Exceptional IEEE Floating Point Numbers
On Sat, Apr 24, 2010 at 5:56 AM, Barak A. Pearlmutter ba...@cs.nuim.ie wrote: Even deriving(Ord) only produces compare and relies on standard definitions for other methods. I don't think that's actually a problem. Surely the IEEE Floating Point types would give their own definitions of not just compare but also , =, etc, overriding the problematic deriving(Ord) definitions of comparison in terms of compare and vice-versa. There is the issue of deriving Ord for algebraic types that include Float. data Foo = Foo Float deriving (Show, Eq, Ord) *Main Foo (0/0) Foo (0/0) True *Main 0/0 0/0 False If compare (0/0) (0/0) = _|_, then Foo (0/0) == Foo (0/0) = _|_. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The instability of Haskell libraries
On Fri, Apr 23, 2010 at 10:11 PM, John Goerzen jgoer...@complete.org wrote: Don Stewart wrote: Oh, the Platform has very strict standards about APIs, When a package may be added: http://trac.haskell.org/haskell-platform/wiki/AddingPackages That looks like a very solid document. Does it also apply when considering upgrading a package already in the platform to a newer version? Also, I notice that http://haskell.org/haskellwiki/Package_versioning_policy does not mention adding new instances, which caused a problem in the past. I would argue that this ought to mandate at least a new A.B.C version, if not a new A.B. Adding or removing instances requires a new major version. See section 2: | If any entity was removed, or the types of any entities or the definitions of | datatypes or classes were changed, or instances were added or removed, | then the new A.B must be greater than the previous A.B. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Move MonadIO to base
On Sun, Apr 18, 2010 at 5:02 PM, wren ng thornton w...@community.haskell.org wrote: Heinrich Apfelmus wrote: Anders Kaseorg wrote: This concept can also be generalized to monad transformers: class MonadTrans t = MonadTransMorph t where morph :: Monad m = (forall b. (t m a - m b) - m b) - t m a [...] However, not all control operators can be lifted this way. Essentially, while you may downgrade an arbitrary selection of t m a values you may only promote one m a in return and all have to share the same return type a . In particular, it's not possible to implement lift :: (Monad m, MonadTrans t) = m a - t m a Why not? * morph says m(t m a) is a subset of (t m a) * Monad m says we can fmap :: (a-b) - (m a-m b) * Monad (t m) says we can return :: a - t m a lift ma = morph (\k - k (fmap return ma)) Maybe something like this? lift m = morph (\k - m = k . return) -- n.b., return and = are from different monads Again, having m(t m a)-(t m a) is strictly more expressive than only having (m a)-(t m a) because the former may avail itself of operations/operators of t. join . lift :: m (t m a) - t m a morph is more powerful than lift, but it isn't because of the type. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Integers v ints
On Thu, Apr 1, 2010 at 5:27 AM, Jens Blanck jens.bla...@gmail.com wrote: I was wondering if someone could give me some references to when and why the choice was made to default integral numerical literals to Integer rather than to Int in Haskell. Also, if you are aware of similar discussions in other languages. I'd like to use this information to make an analogous case for defaulting real numerical literals (well, the literals are likely to be in scientific notation, i.e., floating point) to some data type of computable reals rather than to floating point Double. Integer (and Rational) have decidable equality testing. I don't think the same can be said for computable reals. (Does pi == pi? How about 2 * asin 1?) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC vs GCC
On Sat, Mar 27, 2010 at 12:56 AM, Thomas DuBuisson thomas.dubuis...@gmail.com wrote: Using bang patterns didn't help almost anything here. Using rem instead of mod made the time go from 45s to 40s. Now, using -fvia-C really helped (when I used rem but not using mod). It went down to 10s. Bang patterns should have helped tons - it isn't GHC thats at fault here and yes it does tco. I attached a version w/ excessive bangs below. Did you compile with ghc --make -O3 -fforce-recomp? Does -O3 actually do anything? GHC only goes up to -O2. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC vs GCC
On Sat, Mar 27, 2010 at 1:45 PM, Tillmann Rendel ren...@mathematik.uni-marburg.de wrote: Jan-Willem Maessen wrote: It's worth pointing out that there's a bit of bang-pattern mysticism going on in this conversation (which has not been uncommon of late!). A non-buggy strictness analyzer should expose the strictness of these functions without difficulty. Could the result of strictness analysis reported in terms of the original Haskell program? That would be nice. Even if you're willing to read core, I'm not aware that the output of -ddump-stranal is explained anywhere. Incidentally, the results of -ddump-simpl when running on -O2 say that GHC has unboxed every argument except the first argument to rangeJ. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: data-category, restricted categories
On Fri, Mar 26, 2010 at 11:07 AM, Edward Kmett ekm...@gmail.com wrote: On Fri, Mar 26, 2010 at 11:04 AM, Edward Kmett ekm...@gmail.com wrote: -- as long as you're ignoring 'seq' terminateSeq :: a - Unit terminateSeq a = a `seq` unit Er ignore that language about seq. a `seq` unit is either another bottom or undefined, so there remains one canonical morphism even in the presence of seq (ignoring unsafePerformIO) =) It all depends on how you define equality for functions. If you mean indistinguishable in contexts which may involve seq, then there are at least two values of type Unit - (). foo :: (Unit - ()) - () foo x = x `seq` () foo terminate = () foo undefined = undefined Even this uses the convention that undefined = error whatever = loop, which isn't technically true, since you can use exception handling to write code which treats them differently. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why is it so different between 6.12.1 and 6.10.4_1 ?
On Fri, Mar 26, 2010 at 8:20 PM, zaxis z_a...@163.com wrote: In 6.12.1 under archlinux let f x y z = x + y + z :t f f :: (Num a) = a - a - a - a :t (=) . f (=) . f :: (Num a) = a - ((a - a) - a - b) - a - b ((=) . f) 1 (\f x - f x) 2 5 In 6.10.4_1 under freebsd let f x y z = x + y + z *Money :t f f :: (Num a) = a - a - a - a :t (=) . f (=) . f :: (Monad ((-) a), Num a) = a - ((a - a) - a - b) - a - b ((=) . f) 1 (\f x - f x) 2 interactive:1:1: No instance for (Monad ((-) a)) arising from a use of `=' at interactive:1:1-5 Possible fix: add an instance declaration for (Monad ((-) a)) In the first argument of `(.)', namely `(=)' In the expression: ((=) . f) 1 (\ f x - f x) 2 In the definition of `it': it = ((=) . f) 1 (\ f x - f x) 2 It looks like you have the instance Monad ((-) a) loaded in 6.12, but not in 6.10.4. In don't know of any changes regarding that instance in 6.12, but instances stick around in ghci even after their module is unloaded, so you might have (indirectly) loaded Control.Monad.Instances at some point in your 6.12 session. Try starting a fresh ghci 6.12 and see what that does. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why is it so different between 6.12.1 and 6.10.4_1 ?
On Fri, Mar 26, 2010 at 8:59 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: zaxis z_a...@163.com writes: In 6.10.4_1 under freebsd let f x y z = x + y + z *Money :t f f :: (Num a) = a - a - a - a :t (=) . f (=) . f :: (Monad ((-) a), Num a) = a - ((a - a) - a - b) - a - b ((=) . f) 1 (\f x - f x) 2 interactive:1:1: No instance for (Monad ((-) a)) arising from a use of `=' at interactive:1:1-5 Possible fix: add an instance declaration for (Monad ((-) a)) In the first argument of `(.)', namely `(=)' In the expression: ((=) . f) 1 (\ f x - f x) 2 In the definition of `it': it = ((=) . f) 1 (\ f x - f x) 2 Some definitions and exports got changed, so in 6.12 the (- a) Monad instance is exported whereas in 6.10 it isn't. What? From where? I thought the whole reason the Monad ((-) a) instance was in Control.Monad.Instances (instead of Prelude) was to retain compatibility with the library report. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why is it so different between 6.12.1 and 6.10.4_1 ?
On Fri, Mar 26, 2010 at 9:13 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: David Menendez d...@zednenem.com writes: On Fri, Mar 26, 2010 at 8:59 PM, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote: Some definitions and exports got changed, so in 6.12 the (- a) Monad instance is exported whereas in 6.10 it isn't. What? From where? I thought the whole reason the Monad ((-) a) instance was in Control.Monad.Instances (instead of Prelude) was to retain compatibility with the library report. I forget the specifics, but we had a discussion on this in #haskell a month or so ago: IIRC either the instance definition's location was changed or else it was re-exported by Control.Monad now or something. Are you sure? This would be a fairly significant change, and there's no mention of it in the 6.12 release notes. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Occurs check error, help!
On Sun, Mar 21, 2010 at 11:31 PM, adamtheturtle kill2thr...@hotmail.com wrote: So I have the code shuffle :: Int - [a] - [a] shuffle i [] = [] shuffle i cards = (cards!!i) : shuffle (fst pair) (delete (cards!!i) cards) where pair = randomR (0, 51) (mkStdGen 42) and it doesn't work, am I missing something? Are you familiar with class constraints? Try looking at the type of delete. (Use :type at the ghci prompt.) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Generating repeatable arbitrary values with QuickCheck 2
On Fri, Feb 5, 2010 at 3:39 PM, Ryan Ingram ryani.s...@gmail.com wrote: On Fri, Feb 5, 2010 at 5:19 AM, Martijn van Steenbergen mart...@van.steenbergen.nl wrote: Ryan Ingram wrote: Unfortunately, this makes things like infinite_xs - sequence (repeat arbitrary) no longer work, since the state never comes out the other side. You're asking to execute an infinite number of monadic actions. How can this ever terminate at all? Stefan already gave an example, but to explain slightly further -- There's nothing magical about monadic actions. It's just another function call. In the case of QuickCheck, Gen is a reader monad with a broken = that changes the state of the generator passed to each side: Incidentally, the alternative Gen I suggested also works for infinite lists. (It's equivalent to StateT StdGen (Reader Int), using the StateT from Control.Monad.State.Lazy.) The problem, as Ryan pointed out, is that you can't access the state after the infinite computation, so you can't create two infinite streams or an infinite tree, which the current definition of Gen allows. More concretely, this works fine: stream = do x - arbitrary xs - stream return (x:xs) but you can't call arbitrary after you call stream broken = do xs - stream y - arbitrary -- can't evaluate until stream is fully evaluated (i.e., never) The present definition of Gen avoids this by splitting the StdGen at every =, but that creates the situation where two expressions which should be equivalent produce different results in some contexts. It isn't clear to me which implementation is best. I lean towards the StateT-like implementation, on the theory that it's limitations are easier to explain, but I guess it comes down to whether we want to make life easier for (a) people creating infinite structures or (b) people who need reproducible results. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Generating repeatable arbitrary values with QuickCheck 2
On Tue, Feb 2, 2010 at 1:48 PM, Ryan Ingram ryani.s...@gmail.com wrote: Gen slightly breaks the monad laws: arbitrary = return is not the same as return () = const arbitrary because each bind splits the generator, so you end up with a different seed passed to arbitrary in these two cases. If the observable value is some random object this is a safe fudge, but if you want repeatable, it doesn't quite work. You need your instances to be exactly identical, down to the associativity of binds, in order to get the same results. We could avoid that problem by redefining Gen as a state transformer monad. newtype Gen a = MkGen { unGen :: StdGen - Int - (a, StdGen) } instance Monad Gen where return a = MkGen $ \r _ - (a,r) MkGen m = k = MkGen $ \r n - let (a,r') = m r n in unGen (k a) r' n I'm pretty sure all the Gen primitives can be similarly redefined. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] very strange utf8 problem
2010/2/1 Günther Schmidt gue.schm...@web.de: Hi all, I know this sounds daft but I do have good reason to ask. Is it possible that GHC's core itself has a problem with a particular Umlaut only? HDBC-ODBC won't read in data from an SQLite database as soon as it comes accross a *lowercase* U-Umlaut (ü) ghci crashes. Other Umlauts (ä, ö and ß) pass however. This is the error message: readUTF8Char: illegal UTF-8 character 252 As I said, other Umlauts do pass. I suspect something is trying to read ISO-Latin-1 data as UTF-8. 252 is the Unicode and Latin-1 code point for ü, but in UTF-8 it's written in two bytes as 0xC3BC. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Capped lists and |append|
On Fri, Jan 8, 2010 at 6:38 PM, John Millikin jmilli...@gmail.com wrote: Earlier today I uploaded the capped-list package; I didn't think there would be any interest, since it's a relatively trivial data structure, but already there's been three emails and an IRC convo about it. In short, this is Heinrich Apfelmus's Train type from http://www.haskell.org/pipermail/haskell-cafe/2009-December/069895.html, which showed up in a thread I posted regarding lazy error handling http://www.haskell.org/pipermail/haskell-cafe/2009-November/069825.html. The structure of a Train / CappedList (I like my name better) is: data Train a b = Wagon a (Train a b) | Loco b data CappedList cap a = Next a (CappedList cap a) | Cap cap The order of the type parameters is important. In particular, Train is a free monad, with (=) acting as a generalized append. instance Monad (Train a) where return = Loco Loco a = f = f a Wagon x t = Wagon x (t = f) Monad instances for CappedList are also possible, but more complex: instance Monoid cap = Monad (CappedList cap) where return a = Next a mempty Cap c = f = Cap c Next a as = f = f a `mappend` (as = f) (I can't check what you've uploaded because Hackage is down, so my apologies if I'm telling you things you already know.) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] (liftM join .) . mapM
On Tue, Dec 29, 2009 at 12:24 PM, Stephen Tetley stephen.tet...@gmail.com wrote: oo is one of of a family of functions I use often to avoid sectioning/composing mania. It's known to Raymond Smullyan fans as 'blackbird', though I call it oo as a pun on Standard MLs o (which is Haskells (.) of course). -- | Compose an arity 1 function with an arity 2 function. -- B1 - blackbird oo :: (c - d) - (a - b - c) - a - b - d oo f g = (f .) . g Extending the arity works quite nicely too: -- | Compose an arity 1 function with an arity 3 function. -- B2 - bunting ooo :: (d - e) - (a - b - c - d) - a - b - c - e ooo f g = ((f .) .) . g ... and so on. I've used `` but some how never needed `o`. Due to their typographical appearance in infix form, the family name I have for them is specs (i.e. glasses, googles...) - `oo` Why restrict yourself to functions? You can generalize this to arbitrary stacks of functors. oo :: (Functor f, Functor g) = (a - b) - f (g a) - f (g b) oo = fmap . fmap ooo :: (Functor f, Functor g, Functor h) = (a - b) - f (g (h a)) - f (g (h b)) ooo = oo . fmap etc. (Unfortunately, the Functor ((-) a) instance is orphaned in Control.Monad.Instances, at least until some future Haskell revision finally adds it to the Prelude.) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parse do block problem
On Mon, Dec 21, 2009 at 11:14 PM, joeltt j...@harpsoft.com wrote: I'm trying to write my first Haskell program. The below is the first real logic block I've tried to write, unfortunately I get a The last statement in a 'do' construct must be an expression error when loading the method. However, the location of this problem isn't very clear. Is there a way to get more detailed parse message from Haskell, or can someone tell me where the problem is (and better why?). I don't think I actually need to use a do IO/Monad theme here, but its not clear to me either way. This isn't homework, its just for fun... do_solve_iter guess tried = do let actual = count_occurences guess if guess == actual then putStrLn ANSWER!! else if (find (==actual) tried) == Just actual then do putStrLn NO ANSWER! putStrLn tried else do putStrLn ITER do_solve_iter actual (actual : tried) Assuming your indentation didn't get lost in transmission, your problem is the line if guess == actual, which needs to be at the same level of indentation as let actual As written, the do-block is terminating after the let-statement, which isn't permitted. Also, unless there is more to the function, you don't really need the outermost do-block at all. You can rewrite it easily as a let...in expression, or move the definition of actual to a where clause and use guards to avoid the nested if-expressions. do_solve_iter guess tried | guess == actual = putStrLn ANSWER!! | find (==actual) tried == Just actual = do putStrLn NO ANSWER putStrLn tried | otherwise = do putStrLn ITER do_solve_iter actual (actual : tried) where actual = count_occurences guess -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Rebox Package or To Hackage or not to Hackage
On Tue, Dec 8, 2009 at 4:25 PM, Vitaliy Akimov vitaliy.aki...@gmail.com wrote: Hi John, I don't know if this is useful for you, but these are instances of Cofunctor's comap. For example if we use TypeCompose package we have: rebox f = unFlip . cofmap f . Flip Alternately, rebox = flip (.) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What is the rank of a polymorphic type?
On Sun, Dec 6, 2009 at 8:39 AM, Dan Doel dan.d...@gmail.com wrote: Apologies for the double-reply... Your mail prompted me to finally get around to adding a mono/polytype system to an interpreter I've been working on for pure type systems, to see what a GHC-alike type system would look like. Here's what I came up with. Have you read Henk: a typed intermediate language by Simon Peyton Jones and Erik Meijer? In section 4, they describe a PTS very similar to yours. http://research.microsoft.com/en-us/um/people/emeijer/Papers/Henk.pdf -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Are there standard idioms for lazy, pure error handling?
On Fri, Dec 4, 2009 at 1:14 PM, Jason McCarty jmcca...@sent.com wrote: wren ng thornton wrote: concat1 :: T a b - (b - T a b) - T a b This could just as easily be concat :: T a b - (b - T a c) - T a c right? It's a little weird to call this concatenation, but I bet it could come in handy. T a is, among other things, the free monad for the functor (,) a. The concat you describe is the monadic bind. data T a b = D b | W a (T a b) instance Monad (T a) where return = D D b = f = f b W a t = f = W a (t = f) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Optimization with Strings ?
On Thu, Dec 3, 2009 at 12:32 PM, Alec Berryman a...@thened.net wrote: Emmanuel CHANTREAU on 2009-12-03 13:03:02 +0100: In my futur program, it use a lot of binary trees with strings (words) as leaf. There is just arround 1000 words and they will appear a lot of times. The program will possibly consume a lot of process and memory (it is a mathematics proover). I began this program in C++ but haskell has a prety good speed and memory footprint and is easier. But I don't know if it worth to do this optimization: having a dictionary to translate string words in Int. The answer depends on the automatic optimizations in GHC, because GHC could compare quickely two strings if it is the same object, so it depends if program generated by GHC have a dictionary (tree) of strings internaly. Someone knows this ? I don't know of a library to intern strings, but it's not too hard to implement. I couldn't find the code I wrote to do this, but I looked around a bit and this is about what I remember doing: http://www.haskell.org/pipermail/haskell-cafe/2005-June/010335.html For the application I was using, interning strings did provide a significant reduction in memory, but for whatever reason didn't help with speed. I'd use a trie. Edison provides Data.Edison.Assoc.TernaryTrie, and there are a few other trie packages at hackage. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Implicit newtype unwrapping
On Thu, Dec 3, 2009 at 6:28 AM, Joachim Breitner m...@joachim-breitner.de wrote: Hi, Am Donnerstag, den 03.12.2009, 11:13 + schrieb Matthew Pocock: Perhaps what you are looking for is a more powerful defining semantics? newtype MyFoo = Foo defining (Foo(..)) -- all class instances that Foo has are delegated through from MyFoo it goes into the right direction, but I’d also like to have this also capeable to derive single functions (giving them a new name), and not only class instances. Something like the restricted type synonym extension in Hugs? http://cvs.haskell.org/Hugs/pages/users_guide/restricted-synonyms.html -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Implicit newtype unwrapping
On Wed, Dec 2, 2009 at 7:16 PM, Martijn van Steenbergen mart...@van.steenbergen.nl wrote: So here's a totally wild idea Sjoerd and I came up with. What if newtypes were unwrapped implicitly? As several have suggested, this creates ambiguity. But it might be handy to have a way to declare a scope in which the newtype is transparent. E.g., newtype N = N T f :: T - T - T f = ... open N in -- in this block, N is treated as a synonym for T g :: N - N - N g = f This is similar to the restricted type synonyms feature in Hugs, and I think it's straightforward to encode in GHC's System FC. From my perspective, the primary advantage to a feature like this is that it avoids the need to convert [N] to [T], which under the current system effectively requires mapping an identity function over the entire list. But that also exposes the danger of this idea, where GADTs and type families are involved. data G where A :: G N B :: G T a :: G N - N a ~A = N -- should never fail, because A is the only (non-bottom) value of type G N. Now, what stops me from writing something like this? open N in ... a B ... (See the discussion at http://hackage.haskell.org/trac/ghc/ticket/1496 for how this problem crops up with generalized newtype deriving.) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Are there standard idioms for lazy, pure error handling?
On Tue, Dec 1, 2009 at 5:29 AM, Heinrich Apfelmus apfel...@quantentunnel.de wrote: Duncan Coutts wrote: On Mon, 2009-11-30 at 06:08 +, Malcolm Wallace wrote: However, if you really want to terminate the stream at the first error, and to reflect this in the type, then I guess you can define your own list type: data ListThenError e a = Cons a (ListThenError e a) | Error e Of course this has the disadvantage that then your consumer must change to use this type too. I've been using this list type quite a lot recently. It's in the 'tar' package for example. It comes with variants of the standard functions foldl, foldr, unfoldr that take into account the error possibility. At some point we should probably make a package to standardise and document this lazy error handling idiom. I propose to (trivially) generalize this type to list with an end data ListEnd a b = Cons a (ListEnd a b) | End b because it may have other uses than just lazy error handling. This is almost a composition of a non-determism monad transformer with an exception monad. Specifically, LogicT (Either e) a is (almost) isomorphic with data NX e a = Cons a (NX e a) | Nil | Error e reflect :: NX e a - LogicT (Either e) a reflect (Cons a r) = return a `mplus` reflect r reflect Nil = mzero reflect (Error e) = lift (Left e) reify :: LogicT (Either e) a - NX e a reify m = j $ runLogicT m (\a - Right . Cons a . j) (Right Nil) where j = either Error id -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Existencial Types
On Tue, Dec 1, 2009 at 1:00 PM, rodrigo.bonifacio rodrigo.bonifa...@uol.com.br wrote: Dear all, I wrote the following types: class Transformation t where (+) :: t - SPLModel - InstanceModel - InstanceModel data Configuration = forall t . Transformation t = Configuration (FeatureExpression, [t]) type ConfigurationKnowledge = [Configuration] I tried to write a function that retrieves the list of transformations of a configuration. Bellow a code snip of such a function. transformations ck fc = concat [snd c | (Configuration c) - ck, eval fc (fst c)] However, compiling this I got: --- Inferred type is less polymorphic than expected Quantified type variable `t' escapes When checking an existential match that binds c :: (FeatureModel.Types.FeatureExpression, [t]) The pattern(s) have type(s): Configuration The body has type: [t] In a stmt of a list comprehension: (Configuration c) - ck In the first argument of `concat', namely `[snd c | (Configuration c) - ck, eval fc (fst c)]' --- How can I fix this problem? The problem is that transformations is creating a heterogenous list, i.e., there is no guarantee that the contents of the list all have the same type. You can get around this by declaring a type representing any transformation, data SomeTransformation = forall t. Transformation t = ST t and having transformation return a list of those. However, if Transformation really only has one member function, you'd be better off eliminating the existential types entirely. e.g., data Configuration = Configuration FeatureExpression (SPLModel - InstanceModel - InstanceModel) -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Mystery operator?
On Mon, Nov 30, 2009 at 2:01 PM, michael rice nowg...@yahoo.com wrote: Hi all, A lot of things posted here I wasn't aware of. My original example involved ~(x,y), so, returning to that context, how would these two simple cases vary: add2 :: (Int,Int) - Int add2 (x,y) = x+y add2 :: (Int,Int) - Int add2 ~(x,y) = x+y I guess what I'm looking for is the concept that would dictate choosing one over the other. These particular two functions are identical, because (+) is strict for Ints. But consider these two functions: swap ~(x,y) = (y,x) swap' (x,y) = (y,x) swap is non-strict, and swap' is strict. swap _|_ = (_|_, _|_) swap' _|_ = _|_ -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] instance Binary UTCTime (Was: Oprhan instances)
On Sun, Nov 29, 2009 at 8:37 AM, Duncan Coutts duncan.cou...@googlemail.com wrote: On Thu, 2009-11-26 at 16:40 -0500, David Menendez wrote: The problem with this solution is that it doesn't scale. If we have M packages providing types and N packages providing classes, then we need M*N additional packages for orphans. The best long-term solution is probably extending Cabal to handle this more transparently, perhaps by allowing packages to depend on flagged versions of other packages (e.g., foomonad = 4.0 4.1 HAS_MTL) Not going to happen. Such packages could not be translated into binary distro packages. Do you mean that specific idea won't happen, or that no attempt will be made to reduce the orphan problem? -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] instance Binary UTCTime (Was: Oprhan instances)
On Thu, Nov 26, 2009 at 3:47 PM, Antoine Latter aslat...@gmail.com wrote: Lets say I want to provide an alternate or additional library of monad transformer data types. To make these types maximally useful, they should implement the typeclasses in the mtl package and in the monads-tf package. The only way to do this in a reasonable way is with multiple packages and orphan instances: mypackage mypackage-classes-tf mypackage-classes-fd where the 'classes' packages do nothing but provide class implementations. This is the method I'm using for my own monad transformer library. I initially considered using a flag to specify which instances to provide, but I concluded that providing a consistent API was more important than avoiding orphan instances. The problem with this solution is that it doesn't scale. If we have M packages providing types and N packages providing classes, then we need M*N additional packages for orphans. The best long-term solution is probably extending Cabal to handle this more transparently, perhaps by allowing packages to depend on flagged versions of other packages (e.g., foomonad = 4.0 4.1 HAS_MTL) or some sort of bundled intersection packages. But then we're in a tight spot if someone doesn't notice that I have the mypackage-classes-tf package released, provides their own instances, and ships them in a library. Am I missing something? And how can we extend the language to make this better? Does anything short of class-instance explicit import/export make this better? With FlexibleContexts, GHC will accept code that depends on not-yet-known instances. {-# LANGUAGE FlexibleContexts #-} module Foo where foo :: (Monad (Either Char)) = Int - Either Char Bool foo i = do if i 0 then Left 'a' else Right () return False If I write another module that imports Foo and has an instance for Monad (Either Char) in scope, I can call foo. Otherwise, I get a type error. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Possible FGL bug
On Wed, Nov 25, 2009 at 6:28 AM, Neil Brown nc...@kent.ac.uk wrote: It looks like a bug to me. Can you show an exact list of nodes and edges that is causing mkGraph to fail? Or is that what you have displayed, and I can't parse it properly? From what I can tell, insEdge inserts an edge between two nodes which are already in the graph. The code is calling insEdge on arbitrarily-labeled nodes, which may not exist in the graph. Instead of picking arbitrary node labels, try selecting arbitrary elements from the list of node labels. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Possible FGL bug
On Wed, Nov 25, 2009 at 11:02 AM, Neil Brown nc...@kent.ac.uk wrote: David Menendez wrote: From what I can tell, insEdge inserts an edge between two nodes which are already in the graph. The code is calling insEdge on arbitrarily-labeled nodes, which may not exist in the graph. That's what I thought initially, but in fact what it is doing is exactly what you suggest: Instead of picking arbitrary node labels, try selecting arbitrary elements from the list of node labels. That nGen = elements ns line assigns into nGen a random generator that will pick from ns, the list of nodes. You're right. I've tried this in ghci, and I'm not able to reproduce the error. I did get an exception from QuickCheck when it tried to call elements on an empty list, though. This code works fine for me: a :: Gen ([LNode Char], [LEdge Char], Gr Char Char) a = do NonEmpty ns' - arbitrary let ns = nub ns' let nGen = elements ns lns - mapM (\n - liftM ((,) n) arbitrary) ns les - listOf $ liftM3 (,,) nGen nGen arbitrary return (lns, les, mkGraph lns les) I suspect that there's no value to generating an arbitrary list of node IDs, as opposed to something like: ns - liftM (\(Positive n) - [0..n]) arbitrary -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Status of TypeDirectedNameResolution proposal?
On Wed, Nov 18, 2009 at 4:12 PM, Edward Kmett ekm...@gmail.com wrote: Qualified imports are some times problematic when you need to work with classes from the module. You can't define a member of two instances from different two modules that define classes with conflicting member names. This can lead to situations where you have no option but to have orphan instances. module Bar where class Foo a where foo :: a module Baz where class Quux a where foo :: a module Quaffle where import qualified Bar import qualified Baz instance Bar.Foo Int where Bar.foo = 1 -- ^- syntax error. instance Baz.Quux Int where Baz.foo = 2 I suppose this could possibly be fixed if something deep in the parser allowed a QName there. Try Quaffle without the qualifications. module Quaffle where import qualified Bar import qualified Baz instance Bar.Foo Int where foo = 1 instance Baz.Quux Int where foo = 2 -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[Haskell-cafe] cursive to foldr
On Tue, Nov 17, 2009 at 6:31 PM, Ezra Lalonde ezra.lalo...@gmail.com wrote: Using the same basic structure you did, and foldr, I think below is the simplest method: import Data.Maybe searchList :: (a - Bool) - [a] - Maybe [a] searchList p xs = foldr (\x acc - if p x then Just (x: fromMaybe [] acc) else acc) Nothing xs This might be considered simpler: searchList p = foldr (\x - if p x then Just . maybe [x] (x:) else id) Nothing The real problem with searchList is that it's strict and can't be made lazy. Because it returns Nothing when nothing matches the predicate, it has to traverse the entire list before returning anything. Instead, I would recommend filter, which can be used as-is or defined in terms of foldr. filter p = foldr (\x - if p x then (x:) else id) [] Compare the behavior of searchList even [0..] and filter even [0..]. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[Haskell-cafe] cursive to foldr
On Tue, Nov 17, 2009 at 10:01 PM, Luke Palmer lrpal...@gmail.com wrote: filter even [0..] -- [0,2,4,6,8,...] searchList even [0...] -- Just [0,2,4,6,8,...] searchList gives Nothing in exactly those cases that filter gives []. They give _|_ in exactly the same situations. searchList could well be defined as: searchList p xs = if null ys then Nothing else Just ys where ys = filter p xs null is strict, so searchList is just as strict as filter. You're right. I was thinking of traverse with an exception monad. To make up for it, I'll note that with the recently (re)proposed mfilter, you can define searchList as: searchList p = mfilter (not . null) . Just . filter p -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A small (?) problem with type families
On Fri, Nov 13, 2009 at 3:26 PM, Andy Gimblett hask...@gimbo.org.uk wrote: First a type family where the type Y is functionally dependent on the type X, and we have a function from Y to (). class X a where type Y a enact :: Y a - () This is ambiguous. Type families are not injective (that is, Y a ~ Y b does not imply a ~ b), so there's no way for the compiler to figure out which instance of X is being used when it encounters enact. Given these instances, instance X Int where type Y Int = Bool enact _ = () instance X Char where type Y Char = Bool enact _ = undefined What is enact False? I recall seeing a discussion of this in the GHC documentation, but I can't seem to locate it. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A small (?) problem with type families
On Fri, Nov 13, 2009 at 4:00 PM, Daniel Fischer daniel.is.fisc...@web.de wrote: Am Freitag 13 November 2009 21:36:59 schrieb David Menendez: I recall seeing a discussion of this in the GHC documentation, but I can't seem to locate it. Perhaps http://www.haskell.org/haskellwiki/GHC/Type_families#Frequently_asked_questions ? That's the one. I keep forgetting there's additional material on the wiki. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe