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: Help with TAP implemation in haskell (Krzysztof Skrz?tnicki)
2. Re: Help with TAP implemation in haskell (Felipe Lessa)
3. Re: Help with TAP implemation in haskell
(Brandon S. Allbery KF8NH)
4. Defeating type inference (Philip Scott)
5. Re: Defeating type inference (Antoine Latter)
6. Re: Defeating type inference (Alexander Dunlap)
7. how to instance a class (Daneel Yaitskov)
8. Re: how to instance a class (Thomas Davie)
----------------------------------------------------------------------
Message: 1
Date: Wed, 25 Feb 2009 03:07:09 +0100
From: Krzysztof Skrz?tnicki <[email protected]>
Subject: Re: [Haskell-beginners] Help with TAP implemation in haskell
To: Patrick LeBoutillier <[email protected]>
Cc: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Wed, Feb 25, 2009 at 02:32, Patrick LeBoutillier
<[email protected]> wrote:
> I'm having problems implementing the equivalent of this function in
> haskell. Inside a do block, is there a way to terminate the function
> immediately and return a result ("return" in the imperative sense, not
> the Haskell sense)? If not, must one really use deeply nested
> if/then/else statements to treat these special cases? All I could come
> up was this, which I find quite ugly:
For complex control flow continuation monad can be quite useful. But
one must be careful not to abuse it. Code with heavy use of
continuations can be very hard to follow and hard to debug as well.
Here is an example:
module Main where
import Control.Monad.Cont
checkErrors :: Int -> Maybe String
checkErrors ident =
(`runCont` id) $ do
response <- callCC $ \exit -> do
when (ident == 1) (exit . Just $ "Error! 1!")
when (ident == 2) (exit . Just $ "Error! 2!")
when (ident == 3) (exit . Just $ "Error! 3!")
when (ident == 4) (exit . Just $ "Error! 4!")
when (ident == 5) (exit . Just $ "Error! 5!")
return Nothing
return response
main = forever $ getLine >>= \n -> print (checkErrors (read n))
It runs :
$ ./callcc
0
Nothing
1
Just "Error! 1!"
5
Just "Error! 5!"
3
Just "Error! 3!"
2
Just "Error! 2!"
1
Just "Error! 1!"
9
Nothing
8
Nothing
^C
Please read documentation on Control.Monad.Cont. There are more
elaborate explanations there.
All best
Christopher SkrzÄtnicki
------------------------------
Message: 2
Date: Tue, 24 Feb 2009 23:38:42 -0300
From: Felipe Lessa <[email protected]>
Subject: Re: [Haskell-beginners] Help with TAP implemation in haskell
To: Patrick LeBoutillier <[email protected]>
Cc: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Tue, Feb 24, 2009 at 10:32 PM, Patrick LeBoutillier
<[email protected]> wrote:
> _cleanup :: Int -> TAP Int
> _cleanup rc = do
> Â Â ts <- get
> Â Â if (not $ planSet ts)
> Â Â Â Â then do
> Â Â Â Â Â Â diag "Looks like your test died before it could output
> anything."
> Â Â Â Â Â Â return rc
> Â Â Â Â else if (testDied ts)
> Â Â Â Â Â Â then do
> Â Â Â Â Â Â Â Â diag $ "Looks like your test died just after " ++
> (show $ executedTests ts)
> Â Â Â Â Â Â Â Â return rc
> Â Â Â Â Â Â else ...
_cleanup rc = do
ts <- get
let err | not (planSet ts) = diag "Looks like...anything."
| testDied ts = diag $ "Looks like...after " ++ show
(executedTests ts)
| otherwise = return () -- assuming diag :: String -> TAP ()
err >> return rc
or maybe
_cleanup rc = get >>= showErrs >> return rc
where
showErrs ts
| not (planSet ts) = diag "Looks like...anything."
| testDied ts = diag $ "Looks like...after " ++ show
(executedTests ts)
| otherwise = return ()
HTH,
--
Felipe.
------------------------------
Message: 3
Date: Tue, 24 Feb 2009 21:42:09 -0500
From: "Brandon S. Allbery KF8NH" <[email protected]>
Subject: Re: [Haskell-beginners] Help with TAP implemation in haskell
To: Patrick LeBoutillier <[email protected]>
Cc: beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
On 2009 Feb 24, at 20:32, Patrick LeBoutillier wrote:
> I'm having problems implementing the equivalent of this function in
> haskell. Inside a do block, is there a way to terminate the function
> immediately and return a result ("return" in the imperative sense, not
Take a look at MonadCont. But cleaner is to use Maybe (or MaybeT from
Hackage):
> -- you don't need to define this, it's in the Prelude
> instance Monad Maybe where
> return = Just
> Nothing >>= _ = Nothing
> (Just x) >>= f = f x
So if a test produces Nothing, you short-circuit past the remaining
tests in the (>>=)-chain. But since you need to propagate the TAP
state even when you are given Nothing, you want to wrap the Maybe in a
StateT (and since you have IO at the bottom, you need MaybeT from
Hackage):
> type TAP a = StateT TAPState (MaybeT IO a)
BTW, are you integrating this with QuickCheck and/or SmallCheck? It
might be nice to have
> withTAPplan myPlan $ do
> qTAP propertyOne -- Test.QuickCheck.quickCheck
> sTAP propertyTwo -- Test.SmallCheck.test
> sTAPToDepth 5 property3 -- Test.SmallCheck.smallCheck
> -- need wrappers because e.g. quickCheck won't expect a TAPState
passed in
> -- or you could define (>>=) in your monad to DTRT
Also, in Haskell it is preferable to stay pure, perhaps especially
while testing, so I would ditch the IO in the default case and provide
a secondary function for tests that require IO.
(hm, I sure hope I got this right, since my sinuses are trying to
squeeze my brain out my ears...)
--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [email protected]
system administrator [openafs,heimdal,too many hats] [email protected]
electrical and computer engineering, carnegie mellon university KF8NH
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part
Url :
http://www.haskell.org/pipermail/beginners/attachments/20090224/3b85e11e/PGP-0001.bin
------------------------------
Message: 4
Date: Thu, 26 Feb 2009 00:18:15 +0000
From: Philip Scott <[email protected]>
Subject: [Haskell-beginners] Defeating type inference
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Well, either that or I being an idiot.
Here's a little example. Let us say you had a datatype 'Month'*
data Month = Jan
| Feb
| Mar
| Apr
| May
| Jun
| Jul
| Aug
| Sep
| Oct
| Nov
| Dec
deriving(Show, Eq, Ord, Ix)
What I would like to make is an infinite lazy list of months (called,
rather imaginitively I thought, 'months') that keeps wrapping around.
That is to say, it would make a list like this
[Jan, Feb, ...., Nov, Dec, Jan, Feb, ....., Nov, Dec, ... ad infinitum ]
I am sure you get the picture. My first stab was this:
months = range (Jan, Dec) : months
But of course, what you get here is a list of lists, with each element
being a list of [Jan, Feb, ...., Dec]
So I puzzled for a little bit about how to do this in the most Haskelly
way and I thought of this
months = concat (range (Jan, Dec) : months)
Which should work, right**
But the type checker is not pleased at all and complains:
Couldn't match expected type `[Month]'
against inferred type `Month'
Expected type: [[Month]]
Inferred type: [Month]
In the expression: concat (range (Jan, Dec) : months)
In the definition of `months':
months = concat (range (Jan, Dec) : months)
However, if you use the first definition and make a second function:
months = range (Jan, Dec) : months
realmonths = concat(months)
It is happy and does what one might expect. I thought perhaps I was just
confusing the inference engine so I tried a liberal sprinkling of ::
operators to make my intentions clear, but it still wasn't having any of it.
Any thoughts welcomed!
- Philip
* I am aware that there is plenty of code to handle dates and times
already written, probably much more nicely than mine - this is just a
project I have been hacking at to get to grips with things.
** though I am pretty sure this is the Wrong Way to do this. I suspect
concat takes O(n) time - more elegant approaches would be welcomed!
------------------------------
Message: 5
Date: Wed, 25 Feb 2009 22:41:23 -0600
From: Antoine Latter <[email protected]>
Subject: Re: [Haskell-beginners] Defeating type inference
To: Philip Scott <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On Wed, Feb 25, 2009 at 6:18 PM, Philip Scott <[email protected]> wrote:
> Well, either that or I being an idiot.
>
> Here's a little example. Let us say you had a datatype 'Month'*
>
> data Month = Jan
> | Feb
> | Mar
> | Apr
> | May
> | Jun
> | Jul
> | Aug
> | Sep
> | Oct
> | Nov
> | Dec
> deriving(Show, Eq, Ord, Ix)
<SNIP>
> months = concat (range (Jan, Dec) : months)
>
> Which should work, right**
>
> But the type checker is not pleased at all and complains:
>
> Couldn't match expected type `[Month]'
> against inferred type `Month'
> Expected type: [[Month]]
> Inferred type: [Month]
> In the expression: concat (range (Jan, Dec) : months)
> In the definition of `months':
> months = concat (range (Jan, Dec) : months)
>
> However, if you use the first definition and make a second function:
>
> months = range (Jan, Dec) : months
> realmonths = concat(months)
>
> It is happy and does what one might expect. I thought perhaps I was just
> confusing the inference engine so I tried a liberal sprinkling of ::
> operators to make my intentions clear, but it still wasn't having any of it.
>
Can you post your version of the problem function which includes type
signatures? Can you also write-out a top-level type signature for the
entire expression?
Antoine
------------------------------
Message: 6
Date: Wed, 25 Feb 2009 21:05:12 -0800
From: Alexander Dunlap <[email protected]>
Subject: Re: [Haskell-beginners] Defeating type inference
To: Philip Scott <[email protected]>, [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On Wed, Feb 25, 2009 at 4:18 PM, Philip Scott <[email protected]> wrote:
> months = range (Jan, Dec) : months
>
> But of course, what you get here is a list of lists, with each element being
> a list of [Jan, Feb, ...., Dec]
>
> So I puzzled for a little bit about how to do this in the most Haskelly way
> and I thought of this
>
> months = concat (range (Jan, Dec) : months)
>
> Which should work, right**
>
> But the type checker is not pleased at all and complains:
>
> Couldn't match expected type `[Month]'
> against inferred type `Month'
> Expected type: [[Month]]
> Inferred type: [Month]
> In the expression: concat (range (Jan, Dec) : months)
> In the definition of `months':
> months = concat (range (Jan, Dec) : months)
>
> However, if you use the first definition and make a second function:
>
> months = range (Jan, Dec) : months
> realmonths = concat(months)
>
The problem is that when you go from
> months = range (Jan,Dec) : months
> realmonths = concat months
to
> months = concat (range (Jan,Dec) : months)
you're not just collapsing the two functions, you're changing the
definition (and type!) of "months" which you referred to within the
months function. Since months is a recursive function, you can't
necessary fold in the definition of realmonths because you want the
recursion to apply to the original months, not the original
realmonths.
As you suspected, there are better and simpler ways of doing this
available, although your way is good for getting the hang of
recursion, even though experienced haskellers really don't use
recursion all that much. (Most prefer to use functions that
encapsulate recursion *patterns* such as map, filter, folds and many
more.) You could use list concatentation while keeping the recursion,
as in
> months = range (Jan,Dec) ++ months
Even better, import Data.List and use the built-in cycle function
(http://www.haskell.org/ghc/dist/current/docs/libraries/base/Data-List.html#v%3Acycle):
> months = cycle (range (Jan,Dec))
Hope that helps.
Alex
------------------------------
Message: 7
Date: Thu, 26 Feb 2009 11:02:39 +0300
From: Daneel Yaitskov <[email protected]>
Subject: [Haskell-beginners] how to instance a class
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
Hi,
I study opengl and decided to improve the Vertex3 type.
data Vertex3 a => Vertex3 a! a! a!
a vertex and a vector are same. It is often need to multiple a vector
at a scalar or to calculate a scalar production of two vectors.
I have realized the Num class for the Vertex3 type:
instance (Num a) => Num (Vertex3 a) where
(Vertex3 x y z) * (Vertex3 x' y' z') = (Vertex3 (x*x') (y*y') (z*z'))
(Vertex3 x y z) + (Vertex3 x' y' z') = (Vertex3 (x+x') (y+y') (z+z'))
(Vertex3 x y z) - (Vertex3 x' y' z') = (Vertex3 (x-x') (y-y') (z-z'))
abs (Vertex3 x y z) = (Vertex3 (abs x) (abs y) (abs z))
signum (Vertex3 x y z) = (Vertex3 (signum x) (signum y) (signum z))
negate (Vertex3 x y z) = (Vertex3 (-x) (-y) (-z))
instance (Fractional a) => Fractional (Vertex3 a) where
(Vertex3 x y z) / (Vertex3 x' y' z') = (Vertex3 (x/x') (y/y') (z/z'))
--------------
But I can't instance my own class:
class (Num a) => SVect a where
(***) :: Num b => a -> b -> a
instance (Num t) => SVect (Vertex3 t) where
(Vertex3 x y z) *** c = Vertex3 (c*x) (c*y) (c*z)
GHC posts about the error:
surface.hs:107:36:
Couldn't match expected type `b' against inferred type `t'
`b' is a rigid type variable bound by
the type signature for `***' at surface.hs:103:14
`t' is a rigid type variable bound by
the instance declaration at surface.hs:105:14
In the second argument of `(*)', namely `x'
In the first argument of `Vertex3', namely `(c * x)'
In the expression: Vertex3 (c * x) (c * y) (c * z)
------------------------
I understand the "c" argument must have type as x,y and z, but
I don't know what need to do.
Daneel Yaitskov.
------------------------------
Message: 8
Date: Thu, 26 Feb 2009 09:12:54 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] how to instance a class
To: Daneel Yaitskov <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=WINDOWS-1252; format=flowed;
delsp=yes
On 26 Feb 2009, at 09:02, Daneel Yaitskov wrote:
> --------------
> But I can't instance my own class:
>
> class (Num a) => SVect a where
> (***) :: Num b => a -> b -> a
>
> instance (Num t) => SVect (Vertex3 t) where
> (Vertex3 x y z) *** c = Vertex3 (c*x) (c*y) (c*z)
>
> GHC posts about the error:
>
> surface.hs:107:36:
> Couldn't match expected type `b' against inferred type `t'
> `b' is a rigid type variable bound by
> the type signature for `***' at surface.hs:103:14
> `t' is a rigid type variable bound by
> the instance declaration at surface.hs:105:14
> In the second argument of `(*)', namely `x'
> In the first argument of `Vertex3', namely `(c * x)'
> In the expression: Vertex3 (c * x) (c * y) (c * z)
> ------------------------
>
> I understand the "c" argument must have type as x,y and z, but
> I don't know what need to do.
I don't immediately see what is causing your error, but try
downloading the VectorSpace package off hackage it may save you a
lot of wheel reinventing here.
Bob
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 8, Issue 24
****************************************