Re: [Haskell-cafe] Lenses: Should I declare Getters?

2013-09-10 Thread David Menendez
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

2013-08-17 Thread David Menendez
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

2012-12-01 Thread David Menendez
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

2012-09-11 Thread David Menendez
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

2012-08-22 Thread David Menendez
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

2012-06-17 Thread David Menendez
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

2012-06-16 Thread David Menendez
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

2012-01-21 Thread David Menendez
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

2011-12-21 Thread David Menendez
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

2011-12-21 Thread David Menendez
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

2011-12-21 Thread David Menendez
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

2011-12-19 Thread David Menendez
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

2011-12-03 Thread David Menendez
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

2011-11-21 Thread David Menendez
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

2011-11-20 Thread David Menendez
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

2011-06-21 Thread David Menendez
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.

2011-06-20 Thread David Menendez
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

2011-06-08 Thread David Menendez
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

2011-03-31 Thread David Menendez
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

2011-03-17 Thread David Menendez
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

2011-01-08 Thread David Menendez
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

2011-01-08 Thread David Menendez
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

2011-01-08 Thread David Menendez
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

2011-01-07 Thread David Menendez
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

2010-12-26 Thread David Menendez
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

2010-12-21 Thread David Menendez
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

2010-11-11 Thread David Menendez
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

2010-11-11 Thread David Menendez
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

2010-10-29 Thread David Menendez
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

2010-09-09 Thread David Menendez
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

2010-09-08 Thread David Menendez
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

2010-09-06 Thread David Menendez
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

2010-09-06 Thread David Menendez
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

2010-09-06 Thread David Menendez
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

2010-09-06 Thread David Menendez
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

2010-09-05 Thread David Menendez
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

2010-09-05 Thread David Menendez
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

2010-09-04 Thread David Menendez
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

2010-09-04 Thread David Menendez
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

2010-09-04 Thread David Menendez
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

2010-09-03 Thread David Menendez
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

2010-09-02 Thread David Menendez
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

2010-09-02 Thread David Menendez
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?

2010-08-31 Thread David Menendez
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

2010-08-14 Thread David Menendez
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-07-25 Thread David Menendez
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

2010-07-18 Thread David Menendez
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

2010-07-11 Thread David Menendez
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

2010-07-03 Thread David Menendez
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

2010-07-03 Thread David Menendez
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

2010-07-01 Thread David Menendez
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

2010-07-01 Thread David Menendez
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

2010-06-27 Thread David Menendez
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

2010-06-25 Thread David Menendez
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

2010-06-24 Thread David Menendez
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

2010-06-21 Thread David Menendez
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

2010-06-18 Thread David Menendez
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

2010-05-27 Thread David Menendez
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

2010-05-21 Thread David Menendez
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-05-21 Thread David Menendez
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

2010-05-10 Thread David Menendez
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

2010-05-08 Thread David Menendez
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

2010-05-07 Thread David Menendez
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

2010-05-07 Thread David Menendez
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

2010-04-29 Thread David Menendez
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

2010-04-24 Thread David Menendez
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

2010-04-23 Thread David Menendez
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

2010-04-18 Thread David Menendez
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

2010-04-02 Thread David Menendez
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

2010-03-27 Thread David Menendez
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

2010-03-27 Thread David Menendez
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

2010-03-26 Thread David Menendez
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 ?

2010-03-26 Thread David Menendez
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 ?

2010-03-26 Thread David Menendez
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 ?

2010-03-26 Thread David Menendez
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!

2010-03-21 Thread David Menendez
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

2010-02-05 Thread David Menendez
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

2010-02-02 Thread David Menendez
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-02-01 Thread David Menendez
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|

2010-01-09 Thread David Menendez
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

2009-12-29 Thread David Menendez
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

2009-12-21 Thread David Menendez
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

2009-12-08 Thread David Menendez
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?

2009-12-06 Thread David Menendez
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?

2009-12-04 Thread David Menendez
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 ?

2009-12-03 Thread David Menendez
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

2009-12-03 Thread David Menendez
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

2009-12-03 Thread David Menendez
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?

2009-12-01 Thread David Menendez
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

2009-12-01 Thread David Menendez
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?

2009-11-30 Thread David Menendez
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)

2009-11-29 Thread David Menendez
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)

2009-11-26 Thread David Menendez
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

2009-11-25 Thread David Menendez
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

2009-11-25 Thread David Menendez
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?

2009-11-18 Thread David Menendez
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

2009-11-17 Thread David Menendez
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

2009-11-17 Thread David Menendez
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

2009-11-13 Thread David Menendez
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

2009-11-13 Thread David Menendez
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


  1   2   3   4   >