Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Re: cascade of if statements (Emmanuel Touzery)
2. Re: cascade of if statements (Daniel Trstenjak)
3. netwire accum delayed by one (Nathan H?sken)
4. Re: netwire accum delayed by one (Ertugrul S?ylemez)
5. Re: netwire accum delayed by one (Nathan H?sken)
6. Re: netwire accum delayed by one (Ertugrul S?ylemez)
7. Excellent illustration of using the Haskell types --
revising Richard Bird's floor function so that it works properly
(Costello, Roger L.)
----------------------------------------------------------------------
Message: 1
Date: Sat, 3 Nov 2012 12:02:52 +0100
From: Emmanuel Touzery <[email protected]>
Subject: Re: [Haskell-beginners] cascade of if statements
To: [email protected]
Message-ID:
<CAC42Re=6a9consrFBog-HEphPDEGc8Ddy=eescsxob-xxkv...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
I think you are mistaken, if I understood right one of the key properties
of monads is to ensure order of execution, therefore if you do:
r1 <- m1
r2 <- m2
you are going to run both m1 and m2 (and in this order).
and indeed:
---------
import Control.Monad
(<||>) = liftM2 (||)
f1 = do
putStrLn "f1"
return True
f2 = do
putStrLn "f2"
return True
main = do f1 <||> f2
---------
output is:
f1
f2
On Sat, Nov 3, 2012 at 9:37 AM, Rustom Mody <[email protected]> wrote:
> On Wed, Oct 31, 2012 at 10:44 PM, Daniel Trstenjak <
> [email protected]> wrote:
>
>>
>> (<||>) :: Monad m => m Bool -> m Bool -> m Bool
>> (<||>) m1 m2 = do
>> r1 <- m1
>> if r1 then return True else m2
>>
>>
> We can do some algebraic simplification, using the law
> *if P then True else Q *is same as *P || Q* :
>
>
> (<||>) m1 m2 = do
> r1 <- m1
> r2 <- m2
> return (r1 || r2)
>
> Which reminds me of the definition of liftM2
> (from Control.Monad):
>
> liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
>
> And so we can golf down to:
> (<||>) = liftM2 (||)
>
> Now, instead of using liftM2 from Control.Monad, I could as well use
> liftA2 from Control.Applicative :
>
> (<||>) = liftA2 (||)
>
> So my questions to the experts:
>
> 1> Are these equivalent or am I missing something?
> 2> Any thumb rules on when to use Control.Monad and when to use
> Control.Applicative?
>
> Rusi
> --
> http://blog.languager.org
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121103/5d737d66/attachment-0001.htm>
------------------------------
Message: 2
Date: Sat, 3 Nov 2012 12:13:02 +0100
From: Daniel Trstenjak <[email protected]>
Subject: Re: [Haskell-beginners] cascade of if statements
To: [email protected]
Message-ID: <20121103111302.GA2824@fly>
Content-Type: text/plain; charset=us-ascii
Hi Rusi,
> We can do some algebraic simplification, using the law
> *if P then True else Q *is same as *P || Q* :
>
> (<||>) m1 m2 = do
> r1 <- m1
> r2 <- m2
> return (r1 || r2)
>
> 1> Are these equivalent or am I missing something?
Your operator doesn't behave in the same way, because r2 is computed,
even if r1 is true.
*Main> (putStrLn "m1" >> return True) <||> (putStrLn "m2" >> return True)
m1
m2
True
> 2> Any thumb rules on when to use Control.Monad and when to use
> Control.Applicative?
They're distinct type classes. So the question in this case is rather,
for which type class you need an operator.
When writing your own abstractions, than Applicative seems to be
more appropriate, if you have a more combinatorial abstraction,
like for parsers or HTML form fields.
But I'm also still trying to get a feeling for this.
Greetings,
Daniel
------------------------------
Message: 3
Date: Sat, 03 Nov 2012 13:18:18 +0100
From: Nathan H?sken <[email protected]>
Subject: [Haskell-beginners] netwire accum delayed by one
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hey,
With this netwire based program:
{-# LANGUAGE Arrows #-}
import Control.Wire
import Data.List
mainWire :: WireP () Double
mainWire = proc _ -> do
accum (+) 0 -< 1
main = do
wireLoop mainWire
wireLoop :: WireP () Double -> IO ()
wireLoop w' = do
let (mx, w) = stepWireP w' 1.0 ()
case mx of
Left x -> putStrLn $ show mx
Right x -> putStrLn $ show mx
wireLoop w
I get (output):
Right 0.0
Right 1.0
Right 2.0
...
Should the output not start with 1.0 (and not 0.0)? The accum should be
applied already in the first invocation, should it not?
Regards,
Nathan
------------------------------
Message: 4
Date: Sat, 3 Nov 2012 15:09:25 +0100
From: Ertugrul S?ylemez <[email protected]>
Subject: Re: [Haskell-beginners] netwire accum delayed by one
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
Nathan H?sken <[email protected]> wrote:
> With this netwire based program:
>
> mainWire = proc _ -> do
> accum (+) 0 -< 1
>
> [...]
>
> I get (output):
>
> Right 0.0
> Right 1.0
> Right 2.0
> ...
>
> Should the output not start with 1.0 (and not 0.0)? The accum should
> be applied already in the first invocation, should it not?
Accum is documented to behave like a left scan, which also starts with
the initial value. The reason is that for most applications you want
the data dependency on the previous instant instead of on the current.
Many useful FRP constructs can be (and are) expressed in terms of accum
and accumT.
Greets,
Ertugrul
--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121103/5865543d/attachment-0001.pgp>
------------------------------
Message: 5
Date: Sat, 03 Nov 2012 20:02:49 +0100
From: Nathan H?sken <[email protected]>
Subject: Re: [Haskell-beginners] netwire accum delayed by one
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On 11/03/2012 03:09 PM, Ertugrul S?ylemez wrote:
> Nathan H?sken <[email protected]> wrote:
>
>> With this netwire based program:
>>
>> mainWire = proc _ -> do
>> accum (+) 0 -< 1
>>
>> [...]
>>
>> I get (output):
>>
>> Right 0.0
>> Right 1.0
>> Right 2.0
>> ...
>>
>> Should the output not start with 1.0 (and not 0.0)? The accum should
>> be applied already in the first invocation, should it not?
>
> Accum is documented to behave like a left scan, which also starts with
> the initial value. The reason is that for most applications you want
> the data dependency on the previous instant instead of on the current.
> Many useful FRP constructs can be (and are) expressed in terms of accum
> and accumT.
While I understand the intention, I often have several accums (or
integral which is expressed in terms of accum) chained. For example:
speed :: WireP CollisionData Vector
speed = accum collide initSpeed
where
collide = ...
position :: WireP CollisionData Vector
position = integral_ initPos . speed
which delays the output by 2.
Maybe there should also be a "non delaying" version of accum and integral?
I must admit, I would prefer it to inset delay manually, but that
probably just a matter of taste.
Reagards,
Nathan
------------------------------
Message: 6
Date: Sun, 4 Nov 2012 06:22:05 +0100
From: Ertugrul S?ylemez <[email protected]>
Subject: Re: [Haskell-beginners] netwire accum delayed by one
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
Nathan H?sken <[email protected]> wrote:
> > Accum is documented to behave like a left scan, which also starts
> > with the initial value. The reason is that for most applications
> > you want the data dependency on the previous instant instead of on
> > the current. Many useful FRP constructs can be (and are) expressed
> > in terms of accum and accumT.
>
> While I understand the intention, I often have several accums (or
> integral which is expressed in terms of accum) chained. For example:
>
> speed :: WireP CollisionData Vector
> speed = accum collide initSpeed
> where
> collide = ...
>
> position :: WireP CollisionData Vector
> position = integral_ initPos . speed
>
> which delays the output by 2.
> Maybe there should also be a "non delaying" version of accum and
> integral? I must admit, I would prefer it to inset delay manually, but
> that probably just a matter of taste.
That's how earlier versions of Netwire worked, where you always needed
explicit delays, but that turned out to be very noisy in code. However,
I see why you may want to have the non-delaying versions, so I have
added and released them as version 4.0.2. Along with the change I also
worked around an apparent Haddock bug, which prevented the documentation
from being created for GHC 7.6, so now you get Haddocks, too.
Greets,
Ertugrul
--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121104/b9c0355f/attachment-0001.pgp>
------------------------------
Message: 7
Date: Sun, 4 Nov 2012 09:40:36 +0000
From: "Costello, Roger L." <[email protected]>
Subject: [Haskell-beginners] Excellent illustration of using the
Haskell types -- revising Richard Bird's floor function so that it
works properly
To: "[email protected]" <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="us-ascii"
Hi Folks,
On page 82 of the book "Introduction to Functional Programming using Haskell"
the author Richard Bird provides this sample implementation of the floor
function:
floor x = searchFrom 0
where searchFrom = decrease . upper . lower
lower = until (<=x) decrease
upper = until (>x) increase
decrease n = n - 1
increase n = n + 1
The problem with that implementation is that it does not return an Integer
value; rather, it returns a decimal (Double) value. Here's an example:
floor (-3.4) -- returns (-4.0)
That is wrong. The specification for floor says that it "maps a value of type
Float to a value of type Integer." Clearly it is not producing an Integer
result.
I will now explain how to revise floor so that it returns an Integer value. In
the process we will see an excellent illustration of the Haskell types.
The heart of the problem is with the until function.
Here is how Richard Bird implements it:
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f y = if p y then y else until p f (f y)
It takes three arguments, p, f, and y. Look at the signature of that function.
The type of the third argument, y, dictates the type of the other arguments and
the type of the result--whatever type y is, the other arguments must be the
same type and the result must be the same type.
Function until is first invoked by function lower:
lower = until (<=x) decrease 0
Here are the three arguments provided to function until:
(1) p is the partial function (<=x), where x is the input to the floor
function. Suppose x is this value: x = (-3.4)
(2) f is the function decrease
(3) y is 0
Now you may argue, "Hey, the third argument, y, is 0 and that's an Integer, so
clearly the result of function until will be an Integer." However, that is not
correct. The type of 0 is ambiguous, it could be an Integer or it could be a
Double. This ambiguity can be seen by checking its type using WinGHCi:
:type 0
0 :: Num a => a
The class Num is high up in Haskell's type hierarchy and it represents any
number (Integer, Double, etc.). Thus, we cannot determine the type of function
until's result just by examining its third argument. The other arguments will
determine whether the 0 is an Integer or a Double. Let's examine the first
argument:
p is the partial function (<=x), where x = (-3.4)
p compares "some value" against (-3.4). Let's check the type of (-3.4) using
WinGHCi:
:type (-3.4)
(-3.4) :: Fractional a => a
The datatype Double falls within the class Fractional. So p compares "some
value" against a Double.
Fundamental rule of Haskell: you cannot compare an
Integer against a Double, you can only compare a
Double against a Double.
Recall that p compares "some value" against (-3.4). What is that "some value"?
If we examine the body of function until we see that it is the third argument,
y, and we know that y = 0. Ah, now we know how Haskell will treat 0: since
the 0 is being compared against a Double value Haskell will treat the 0 as a
Double. Okay, now that we know the type of y we can plug it into the type
signature for function until:
until :: (a -> Bool) -> (a -> a) -> Double -> a
All a's must be of the same type, so the other a's must also be Double:
until :: (Double -> Bool) -> (Double -> Double) -> Double -> Double
Therefore function until will return a Double value. For example:
until (<=x) decrease 0 -- returns (0.0)
The output of function until is assigned to function lower:
lower = until (<=x) decrease
So the result of function lower is a Double value.
The output of lower is then input to upper and the Double datatype propagates
through the entire chain of composed functions:
decrease . upper . lower
The result of function floor is therefore a Double value.
Okay, so how do we get floor to return an Integer value? The key is to prevent
p in function until from casting the type of y to a Double. Recall function
lower:
lower = until (<=x) decrease 0
Notice that p is this partial function:
(<=x)
We must modify p to express, "Hey, compare x against an Integer value that has
been cast to a Double value." That is implemented using a Lambda (anonymous)
function:
(\a -> (realToFrac a) <= x)
Read that as: For whatever value, a, is provided convert it to a Fractional
(Double) value and then compare it to x.
Wow!
So we are telling Haskell that the 0 is not to be treated as a Fractional
(Double) value, it is to be treated as a Real (Integer) value.
At last, we can implement function floor and it will return the desired Integer
result:
floor x = searchFrom 0
where searchFrom = decrease . upper . lower
lower = until (\a -> (realToFrac a) <=
x) decrease
upper = until (\a -> (realToFrac a) >
x) increase
decrease n = n - 1
increase n = n + 1
Notice that wherever function until is called (in lower and upper), the first
argument, p, is a Lambda (anonymous) function that takes its argument, a, and
casts it from a Real (Integer) value to a Fractional (Double) value. Here are a
couple examples of using this revised floor function:
floor (-3.4) -- returns (-4)
floor 3.4 -- returns 3
Notice that floor now returns an Integer value, which is what we want.
Here is the signature for floor:
floor :: (Fractional a, Ord a, Real c) => a -> c
Read as: Invoke function floor with a Fractional (Double) value and it will
return a Real (Integer) value.
On page 83 Richard Bird shows a second version of function floor that uses a
binary search:
floor x = searchFrom (-1, 1)
where searchFrom = fst . middle . cross(lower, upper)
lower = until (<= x) double
upper = until (> x) double
middle = until done improve
done (m, n) = (m + 1 == n)
improve (m, n) = if p <= x then (p, n) else (m, p)
where p = (m + n) div 2
That has multiple problems. First, it is syntactically not a well-formed
Haskell program because the div operator (on the last line) must have back
ticks ( ` ) surrounding it:
where p = (m + n) `div` 2
Second, the functions lower and upper invoke function until. The first argument
to until must be a Lambda function as described above:
lower = until (\m -> (realToFrac m) <= x) double
upper = until (\n -> (realToFrac n) > x) double
Third, the function improve compares p (an Integer) against x (a Double), so p
must be cast to a Fractional (Double) value:
improve (m, n) = if (realToFrac p) <= x then (p, n)
else (m, p)
where p = (m + n) div 2
With those three changes the function works as desired:
floor x = searchFrom (-1, 1)
where searchFrom = fst . middle . cross(lower, upper)
lower = until (\m -> (realToFrac m) <= x) double
upper = until (\n -> (realToFrac n) > x) double
middle = until done improve
done (m, n) = (m + 1 == n)
improve (m, n) = if (realToFrac p) <= x then (p, n)
else (m, p)
where p = (m + n) `div` 2
Here are a couple examples of using the revised floor function:
floor (-3.4) -- returns (-4)
floor 3.4 -- returns 3
Notice that floor now returns an Integer value, which is what we want.
Here is the signature for floor:
floor :: (Fractional a, Ord a, Real c) => a -> c
Read as: Invoke function floor with a Fractional (Double) value and it will
return a Real (Integer) value.
/Roger
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 53, Issue 4
****************************************