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: beginner's type error (Ivan Moore)
2. Re: Need help to edit the Haskell script in Winhugs and
documentation. (Benjamin L.Russell)
3. Re: Need help to edit the Haskell script in Winhugs and
documentation. (Benjamin L.Russell)
4. Re: numerical types, the $ operator (Daniel Fischer)
5. Re: question from Yet Another Haskell Tutorial
(Benjamin L.Russell)
----------------------------------------------------------------------
Message: 1
Date: Fri, 27 Mar 2009 19:44:05 +0000
From: Ivan Moore <[email protected]>
Subject: Re: [Haskell-beginners] beginner's type error
To: Brent Yorgey <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Many thanks for the fantastic answers.
I have a question related to your answer
> The reason (which is a bit confusing) is that it typechecks just
> fine---if there *were* a type which is an instance of both Integral
> and Floating (and I guess round needs RealFrac as well), n could have
> that type. There isn't such a type in the standard libraries, but in
> theory you could make up your own type which is an instance of both.
If there were such a type, could "10" have that type and then would my
problem have not existed? (in which case, why doesn't it!?)
(an answer of - "ask again when you've used the language a bit more"
would be perfectly fine if it requires a lot
more understanding of the language to understand the answer than a
newbie like me has - I'm just curious)
On Fri, Mar 27, 2009 at 1:07 PM, Brent Yorgey <[email protected]> wrote:
> On Thu, Mar 26, 2009 at 10:01:07PM +0000, Ivan Moore wrote:
>> Hi all,
>>
>> consider this very small function:
>>
>> thing n = n + round(sqrt n)
>
> Here's what's going on: since you call sqrt on n, it must have some
> type which is an instance of Floating. However, round can return any
> type which is an instance of Integral, and since you are adding n to
> it, n must have the same type.
>
> This is the takeaway point here: sqrt requires some floating-point
> type (like Float or Double), but round returns an Integral type (like
> Int or Integer) and n can't be both. In particular you can't call
> sqrt on an Integral value. So the fix is to use fromIntegral to
> convert:
>
> thing n = n + round (sqrt (fromIntegral n))
>
>>
>> It loads into ghci with no warnings.
>
> The reason (which is a bit confusing) is that it typechecks just
> fine---if there *were* a type which is an instance of both Integral
> and Floating (and I guess round needs RealFrac as well), n could have
> that type. There isn't such a type in the standard libraries, but in
> theory you could make up your own type which is an instance of both.
>
>> When I try to run "thing 10" I get:
>>
>> *Main> :load c:\temp\statictype.hs
>> [1 of 1] Compiling Main ( C:\temp\statictype.hs, interpreted )
>> Ok, modules loaded: Main.
>> *Main> thing 10
>>
>> <interactive>:1:0:
>> Ambiguous type variable `t' in the constraints:
>> `Integral t' arising from a use of `thing' at <interactive>:1:0-7
>> `RealFrac t' arising from a use of `thing' at <interactive>:1:0-7
>> `Floating t' arising from a use of `thing' at <interactive>:1:0-7
>> Probable fix: add a type signature that fixes these type variable(s)
>>
>> I have tried to add various type signatures (without really knowing
>> what I'm doing!) and haven't been able to get it to work.
>>
>> I am confused about a few things related to this:
>> (a) what type signature fixes it and why it needs any help - it looks
>> like the sort of thing that type inference shouldn't need any help
>> with
>
> The error message is particularly unhelpful here. Adding a type
> signature would only help if you actually had some type which was both
> Integral and Floating, but you don't.
>
>> (b) it looks like a runtime type error and I thought you didn't get
>> runtime type errors in Haskell
>
> You don't. This isn't a runtime type error; the error was generated
> while trying to typecheck the expression 'thing 10' before evaluating
> it.
>
>> (c) if I substitute 10 for n and do "10 + round(sqrt 10)" I get the
>> expected answer 13
>
> This is because numeric literals (like 10) are polymorphic---they can
> have any numeric type. In this case, type inference correctly figures
> out that the first 10 should have type Integer, and the second 10
> should have type Double. The difference is that they are not
> constrained to have the same type---unlike the two occurrences of 'n'
> in your original function.
>
> Confusing, isn't it! It's a shame that numeric types can be so
> confusing, since that's usually one of the first things that people
> run into when learning the language. But I hope this is helpful.
> Feel free to ask if you have more questions.
>
> -Brent
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
------------------------------
Message: 2
Date: Mon, 30 Mar 2009 17:52:34 +0900
From: Benjamin L.Russell <[email protected]>
Subject: [Haskell-beginners] Re: Need help to edit the Haskell script
in Winhugs and documentation.
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=iso-2022-jp
Could you please describe your question more specifically?
-- Benjamin L. Russell
On Sat, 28 Mar 2009 16:48:47 +0000, RAJESH DALSANIYA
<[email protected]> wrote:
>* *
>
>*Both sections relate to the case study: Index for a document of
>text.*
>
>* *
>
>*SECTION A: *
>
>* *
>
>*Given the attached Haskell code which produces an index of words, make the
>following alterations by modifying existing functions and including new
>functions where necessary ? parts 1) to 5):*
>
>* *
>
>*1) **Where a word occurs N times on the same line, ensure
>that the line number occurs n times in the index entry for that word.
>*
>
>* *
>
>*2) **Allow words to be hyphenated and treat a hyphenated
>word as a single word. However, for those words which are split over two
>lines, treat a split word as a single word without the hyphen. *
>
>* *
>
>*3) **Treat a capitalised word (one or more capitals) as
>being different from the word in all lower case (but they should still be
>sorted alphabetically) ? unless it is at the start of a sentence with only
>the initial letter capitalised. A sentence is terminated by a
>$B!F(B.$B!G(B, $B!F(B?$B!G(B or
>$B!F(B!$B!G(B. *
>
>* *
>
>*4) **Make the output more readable in the form of an index
>table in columns with appropriate spacing and without brackets. *
>
>* *
>
>*5) **Include a user-friendly menu, so that the user can
>choose input/output file names or default files, and choose to rerun or
>exit. *
>
>* *
>
>*Parts 1) to 5) may be developed in any order. *
>
>* *
>
>* *
>
>*SECTION B:*
>
>* *
>
>*6) **For your version of function, makeIndex (only), show
>how an alternative ordering of the composed functions would provide a more
>efficient execution of makeIndex. Justify your answer. *
>
>* *
>
>*7) **For the parts 1) to 5) above that you have attempted,
>discuss the use you have made of a) higher-order functions, b) list
>comprehension, c) monadic input/output, d) functional composition, and/or e)
>partial parameterisation (or Curried functions). Include an evaluation of
>how useful your use of these concepts has been.
>*
>
>* *
>
>*
>*
>*
>*
>
>*import Prelude*
>
>* *
>
>*type Doc = String*
>
>*type Line = String*
>
>*type Word = String *
>
>* *
>
>*makeIndex :: Doc -> [ ([Int], Word) ]*
>
>* *
>
>*makeIndex*
>
>* = shorten . -- [([Int], Word)] -> [([Int], Word)]*
>
>* amalgamate .-- [([Int], Word)] -> [([Int], Word)]*
>
>* makeLists . -- [(Int, Word)] -> [([Int], Word)]*
>
>* sortLs . -- [(Int, Word)] -> [(Int, Word)]*
>
>* allNumWords .-- [(Int, Line)] -> [(Int, Word)]*
>
>* numLines . -- [Line] -> [(Int, Line)]*
>
>* splitUp -- Doc -> [Line]*
>
>* *
>
>*splitUp :: Doc -> [Line]*
>
>* *
>
>*splitUp [] = []*
>
>*splitUp text*
>
>* = takeWhile (/='\n') text : -- first line*
>
>* (splitUp . -- splitup other lines*
>
>* dropWhile (==$B!G(B\n$B!G(B) . -- delete 1st newline(s)*
>
>* dropWhile (/='\n')) text -- other lines*
>
>* *
>
>*numLines :: [Line] -> [(Int, Line)]*
>
>* *
>
>*numLines lines -- list of pairs of *
>
>* = zip [1 .. length lines] lines -- line no. & line*
>
>* *
>
>*-- for each line*
>
>*-- a) split into words*
>
>*-- b) attach line no. to each word*
>
>* *
>
>*splitWords :: Line -> [Word] -- a)*
>
>* *
>
>*splitWords [] = []*
>
>*splitWords line *
>
>* = takeWhile isLetter line : -- first word in line*
>
>* (splitWords . -- split other words*
>
>* dropWhile (not.isLetter) . -- delete separators*
>
>* dropWhile isLetter) line -- other words*
>
>* where*
>
>* isLetter ch*
>
>* = ($B!F(Ba$B!G(B<=ch) && (ch<=$B!G(Bz$B!G(B)*
>
>* || ($B!F(BA$B!G(B<=ch) && (ch<=$B!G(BZ$B!G(B)*
>
>* *
>
>*numWords :: (Int, Line) -> [(Int, Word)] -- b)*
>
>* *
>
>*numWords (number, line)*
>
>* = map addLineNum ( splitWords line) -- all line pairs*
>
>* where*
>
>* addLineNum word = (number, word) -- a pair*
>
>* *
>
>*allNumWords :: [(Int, Line)] -> [(Int, Word)]*
>
>* *
>
>*allNumWords = concat . map numWords -- doc pairs *
>
>* *
>
>*sortLs :: [(Int, Word)] -> [(Int, Word)]*
>
>* *
>
>*sortLs [ ] = [ ]*
>
>*sortLs (a:x)*
>
>* = sortLs [b | b <- x, compare b a] -- sort 1st half*
>
>* ++ [a] ++ -- 1st in middle*
>
>* sortLs [b | b <- x, compare a b] -- sort 2nd half*
>
>* where*
>
>* compare (n1, w1) (n2, w2)*
>
>* = (w1 < w2) -- 1st word less*
>
>* || (w1 == w2 && n1 < n2) -- check no. *
>
>* *
>
>*makeLists :: [(Int, Word)] -> [([Int], Word)]*
>
>* *
>
>*makeLists *
>
>* = map mk -- all pairs*
>
>* where mk (num, word) = ([num], word)*
>
>* -- list of single no.*
>
>* *
>
>*amalgamate :: [([Int], Word)] -> [([Int], Word)]*
>
>* *
>
>*amalgamate [ ] = [ ]*
>
>*amalgamate [a] = [a]*
>
>*amalgamate ((n1, w1) : (n2, w2) : rest)-- pairs of pairs*
>
>* | w1 /= w2 = (n1, w1) : amalgamate ((n2, w2) : rest)*
>
>* | otherwise = amalgamate ((n1 ++ n2, w1) : rest)*
>
>* -- if words are same grow list of numbers*
>
>* *
>
>*shorten :: [([Int], Word)] -> [([Int], Word)]*
>
>* *
>
>*shorten*
>
>* = filter long -- keep pairs >4*
>
>* where*
>
>* long (num, word) = length word > 4 -- check word >4*
>
>* *
--
Benjamin L. Russell / DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile: +011 81 80-3603-6725
"Furuike ya, kawazu tobikomu mizu no oto."
-- Matsuo Basho^
------------------------------
Message: 3
Date: Mon, 30 Mar 2009 18:04:17 +0900
From: Benjamin L.Russell <[email protected]>
Subject: [Haskell-beginners] Re: Need help to edit the Haskell script
in Winhugs and documentation.
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=iso-2022-jp
These look like homework questions.
If these are homework questions, while we are all here to help, we
cannot help you unless you provide more information on why you are
stuck. In this regard, the following HaskellWiki article may be of
assistance:
Homework help - HaskellWiki
http://haskell.org/haskellwiki/Homework_help
-- Benjamin L. Russell
On Mon, 30 Mar 2009 17:52:34 +0900, Benjamin L.Russell
<[email protected]> wrote:
>Could you please describe your question more specifically?
>
>-- Benjamin L. Russell
>
>On Sat, 28 Mar 2009 16:48:47 +0000, RAJESH DALSANIYA
><[email protected]> wrote:
>
>>* *
>>
>>*Both sections relate to the case study: Index for a document of
>>text.*
>>
>>* *
>>
>>*SECTION A: *
>>
>>* *
>>
>>*Given the attached Haskell code which produces an index of words, make the
>>following alterations by modifying existing functions and including new
>>functions where necessary ? parts 1) to 5):*
>>
>>* *
>>
>>*1) **Where a word occurs N times on the same line, ensure
>>that the line number occurs n times in the index entry for that word.
>>*
>>
>>* *
>>
>>*2) **Allow words to be hyphenated and treat a hyphenated
>>word as a single word. However, for those words which are split over two
>>lines, treat a split word as a single word without the hyphen. *
>>
>>* *
>>
>>*3) **Treat a capitalised word (one or more capitals) as
>>being different from the word in all lower case (but they should still be
>>sorted alphabetically) ? unless it is at the start of a sentence with only
>>the initial letter capitalised. A sentence is terminated by a
>>$B!F(B.$B!G(B, $B!F(B?$B!G(B or
>>$B!F(B!$B!G(B. *
>>
>>* *
>>
>>*4) **Make the output more readable in the form of an index
>>table in columns with appropriate spacing and without brackets. *
>>
>>* *
>>
>>*5) **Include a user-friendly menu, so that the user can
>>choose input/output file names or default files, and choose to rerun or
>>exit. *
>>
>>* *
>>
>>*Parts 1) to 5) may be developed in any order. *
>>
>>* *
>>
>>* *
>>
>>*SECTION B:*
>>
>>* *
>>
>>*6) **For your version of function, makeIndex (only), show
>>how an alternative ordering of the composed functions would provide a more
>>efficient execution of makeIndex. Justify your answer. *
>>
>>* *
>>
>>*7) **For the parts 1) to 5) above that you have attempted,
>>discuss the use you have made of a) higher-order functions, b) list
>>comprehension, c) monadic input/output, d) functional composition, and/or e)
>>partial parameterisation (or Curried functions). Include an evaluation of
>>how useful your use of these concepts has been.
>>*
>>
>>* *
>>
>>*
>>*
>>*
>>*
>>
>>*import Prelude*
>>
>>* *
>>
>>*type Doc = String*
>>
>>*type Line = String*
>>
>>*type Word = String *
>>
>>* *
>>
>>*makeIndex :: Doc -> [ ([Int], Word) ]*
>>
>>* *
>>
>>*makeIndex*
>>
>>* = shorten . -- [([Int], Word)] -> [([Int], Word)]*
>>
>>* amalgamate .-- [([Int], Word)] -> [([Int], Word)]*
>>
>>* makeLists . -- [(Int, Word)] -> [([Int], Word)]*
>>
>>* sortLs . -- [(Int, Word)] -> [(Int, Word)]*
>>
>>* allNumWords .-- [(Int, Line)] -> [(Int, Word)]*
>>
>>* numLines . -- [Line] -> [(Int, Line)]*
>>
>>* splitUp -- Doc -> [Line]*
>>
>>* *
>>
>>*splitUp :: Doc -> [Line]*
>>
>>* *
>>
>>*splitUp [] = []*
>>
>>*splitUp text*
>>
>>* = takeWhile (/='\n') text : -- first line*
>>
>>* (splitUp . -- splitup other lines*
>>
>>* dropWhile (==$B!G(B\n$B!G(B) . -- delete 1st newline(s)*
>>
>>* dropWhile (/='\n')) text -- other lines*
>>
>>* *
>>
>>*numLines :: [Line] -> [(Int, Line)]*
>>
>>* *
>>
>>*numLines lines -- list of pairs of *
>>
>>* = zip [1 .. length lines] lines -- line no. & line*
>>
>>* *
>>
>>*-- for each line*
>>
>>*-- a) split into words*
>>
>>*-- b) attach line no. to each word*
>>
>>* *
>>
>>*splitWords :: Line -> [Word] -- a)*
>>
>>* *
>>
>>*splitWords [] = []*
>>
>>*splitWords line *
>>
>>* = takeWhile isLetter line : -- first word in line*
>>
>>* (splitWords . -- split other words*
>>
>>* dropWhile (not.isLetter) . -- delete separators*
>>
>>* dropWhile isLetter) line -- other words*
>>
>>* where*
>>
>>* isLetter ch*
>>
>>* = ($B!F(Ba$B!G(B<=ch) && (ch<=$B!G(Bz$B!G(B)*
>>
>>* || ($B!F(BA$B!G(B<=ch) && (ch<=$B!G(BZ$B!G(B)*
>>
>>* *
>>
>>*numWords :: (Int, Line) -> [(Int, Word)] -- b)*
>>
>>* *
>>
>>*numWords (number, line)*
>>
>>* = map addLineNum ( splitWords line) -- all line pairs*
>>
>>* where*
>>
>>* addLineNum word = (number, word) -- a pair*
>>
>>* *
>>
>>*allNumWords :: [(Int, Line)] -> [(Int, Word)]*
>>
>>* *
>>
>>*allNumWords = concat . map numWords -- doc pairs *
>>
>>* *
>>
>>*sortLs :: [(Int, Word)] -> [(Int, Word)]*
>>
>>* *
>>
>>*sortLs [ ] = [ ]*
>>
>>*sortLs (a:x)*
>>
>>* = sortLs [b | b <- x, compare b a] -- sort 1st half*
>>
>>* ++ [a] ++ -- 1st in middle*
>>
>>* sortLs [b | b <- x, compare a b] -- sort 2nd half*
>>
>>* where*
>>
>>* compare (n1, w1) (n2, w2)*
>>
>>* = (w1 < w2) -- 1st word less*
>>
>>* || (w1 == w2 && n1 < n2) -- check no. *
>>
>>* *
>>
>>*makeLists :: [(Int, Word)] -> [([Int], Word)]*
>>
>>* *
>>
>>*makeLists *
>>
>>* = map mk -- all pairs*
>>
>>* where mk (num, word) = ([num], word)*
>>
>>* -- list of single no.*
>>
>>* *
>>
>>*amalgamate :: [([Int], Word)] -> [([Int], Word)]*
>>
>>* *
>>
>>*amalgamate [ ] = [ ]*
>>
>>*amalgamate [a] = [a]*
>>
>>*amalgamate ((n1, w1) : (n2, w2) : rest)-- pairs of pairs*
>>
>>* | w1 /= w2 = (n1, w1) : amalgamate ((n2, w2) : rest)*
>>
>>* | otherwise = amalgamate ((n1 ++ n2, w1) : rest)*
>>
>>* -- if words are same grow list of numbers*
>>
>>* *
>>
>>*shorten :: [([Int], Word)] -> [([Int], Word)]*
>>
>>* *
>>
>>*shorten*
>>
>>* = filter long -- keep pairs >4*
>>
>>* where*
>>
>>* long (num, word) = length word > 4 -- check word >4*
>>
>>* *
--
Benjamin L. Russell / DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile: +011 81 80-3603-6725
"Furuike ya, kawazu tobikomu mizu no oto."
-- Matsuo Basho^
------------------------------
Message: 4
Date: Mon, 30 Mar 2009 12:21:50 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] numerical types, the $ operator
To: Zachary Turner <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-15"
Am Montag 30 März 2009 06:37:57 schrieb Zachary Turner:
> On Sun, Mar 29, 2009 at 6:47 PM, Daniel Fischer
<[email protected]>wrote:
> The &&& operator is pretty sweet, thanks for pointing it out. That's
> pretty much what I was trying to come up with the mapping and mapping2,
Yep. Pretty good thinking, by the way.
> but it's more general and hence more useful.
More general doesn't necessarily imply more useful, specialisation can
sometimes be necessary for performance reasons.
A big advantage of (&&&) and friends is that many Haskellers know them and
won't need to look up the definitions when reading your code, as would be
necessary if you use your own differently named variant.
So if you come up with with generally useful patterns like (|>), mapping and
mapping2, find out whether it's already defined in a library.
Try searching for the type in Hoogle, and if it doesn't find it, ask on the
list.
>
> The "pipelining" operator I defined should definitely be used with care.
> For example, it requires the pipelined argument to be the last argument,
> which is not always the case.
It's the same for ($) and (.).
If your pipeline is too complicated to write it with (|>) and a few flips, you
should
probably write it in a different style anyway.
> And I've also found that with it I tend to
> think about the problem less, and write less efficient code as a result.
> For example given a list of integers, an easy and very readable way to
> remove all multiples of 2 from a list, and then double the remaining items
> could be like this:
>
> let doit x = x |> filter (\y -> y `mod` 2 == 0) |> map (* 2)
>
> as opposed to the more efficient
>
> doit [] = []
> doit (x:xs) | (x `mod` 2 == 0) = doit xs
> doit (x:xs) = (2 * x) : doit xs
>
> since the list is walked twice.
No, thanks to laziness, it's only walked once, the intermediate list won't ever
be
constructed. If there's any performance difference, it should be minuscule.
> (I'm betting someone will respond with a
> cool one-liner here involving function composition or something else that I
> can't think of yet :)
list comprehension:
doit x = [2*y | y <- x, even y]
function composition:
doit = map (*2) . filter even
doit = filter even >>> map (*2)
If you use one of the latter two, be sure to give a type signature, or you'll
probably be bitten by the monomorphism restriction.
------------------------------
Message: 5
Date: Mon, 30 Mar 2009 20:33:29 +0900
From: Benjamin L.Russell <[email protected]>
Subject: [Haskell-beginners] Re: question from Yet Another Haskell
Tutorial
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Sun, 29 Mar 2009 14:45:22 +0200, Daniel Fischer
<[email protected]> wrote:
>Simple mistake. YAHT was never systematically proofread to catch all
>such mistakes, so there are several still in. Nevertheless, it is an
>excellent tutorial.
Thank you both, Michael and Daniel. I have compiled the information
in this thread into a new page, "Errata," in the YAHT Wikibook,
covering discrepancies between the original PDF and corrected HTML
versions of YAHT:
Haskell/YAHT/Errata - Wikibooks, collection of open-content textbooks
http://en.wikibooks.org/wiki/Haskell/YAHT/Errata
Please feel free to add to it or to correct it as would benefit
students of Haskell.
-- Benjamin L. Russell
--
Benjamin L. Russell / DekuDekuplex at Yahoo dot com
http://dekudekuplex.wordpress.com/
Translator/Interpreter / Mobile: +011 81 80-3603-6725
"Furuike ya, kawazu tobikomu mizu no oto."
-- Matsuo Basho^
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 9, Issue 41
****************************************