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. Parsec, comma sperated list with special last element
(Nathan H?sken)
2. Cannot compile "where" in a function (Trung Quang Nguyen)
3. Re: Cannot compile "where" in a function (Brent Yorgey)
4. Re: Parsec, comma sperated list with special last element
(Daniel Trstenjak)
5. Re: Cannot compile "where" in a function (Trung Quang Nguyen)
6. Re: Parsec, comma sperated list with special last element
(Karl Voelker)
----------------------------------------------------------------------
Message: 1
Date: Sun, 16 Dec 2012 17:55:53 +0100
From: Nathan H?sken <[email protected]>
Subject: [Haskell-beginners] Parsec, comma sperated list with special
last element
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hey,
I want to parse a string like this:
<cell>,<cell>,<lastCell>
All cells but the last cell are parsed with "cell", the last one is
parsed with "lastCell".
So I am trying:
file = do
res <- endBy cell (char ',')
l <- lastCell
eof
return res
cell = many1 (noneOf ",")
lastCell = many1 (noneOf "\n")
This results in
unexpected end of input
expecting ","
I am assuming this is because the lastCell is comsumed by a "cell" parser.
lastCell and cell look pretty similar, so the cell parser can does not
fail when presented the <lastCell>.
Can I still do this with "endBy" or is there a better combinator?
Thanks!
Nathan
------------------------------
Message: 2
Date: Sun, 16 Dec 2012 18:08:20 +0100
From: Trung Quang Nguyen <[email protected]>
Subject: [Haskell-beginners] Cannot compile "where" in a function
To: beginners <[email protected]>
Message-ID:
<cals5ubwrftkj5sucngjyd+5k8eiiq2oystvpe4g6rsybc0i...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Hi there,
I'm trying to implement Reverse Polish notation calculator from
learnyouhaskell.com. I want to add one more operator "/", but I cannot
compile. I comment out the line --func (x:y:ys) "/" = (y / x):ys, thing
goes well again. Any body knows the cause of this problem?
--rpn.hs
import System.Environment
import Data.List
solveRPN :: (Num a, Read a) => String -> a
solveRPN = head . foldl func [] . words
where
func (x:y:ys) "+" = (y + x):ys
func (x:y:ys) "-" = (y - x):ys
func (x:y:ys) "*" = (y * x):ys
--func (x:y:ys) "/" = (y / x):ys
func xs numStr = read numStr:xs
main = do
(x:_) <- getArgs
putStrLn $ show $ solveRPN x
I got this:
~/w/r/s/haskell> ghc --make rpn
[1 of 1] Compiling Main ( rpn.hs, rpn.o )
rpn.hs:5:25:
Could not deduce (Fractional a) arising from a use of `func'
from the context (Num a, Read a)
bound by the type signature for
solveRPN :: (Num a, Read a) => String -> a
at rpn.hs:(5,1)-(11,39)
Possible fix:
add (Fractional a) to the context of
the type signature for solveRPN :: (Num a, Read a) => String -> a
In the first argument of `foldl', namely `func'
In the first argument of `(.)', namely `foldl func []'
In the second argument of `(.)', namely `foldl func [] . words'
Thanks in advance!:)
/Trung
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121216/c667b24d/attachment-0001.htm>
------------------------------
Message: 3
Date: Sun, 16 Dec 2012 12:21:15 -0500
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] Cannot compile "where" in a function
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Sun, Dec 16, 2012 at 06:08:20PM +0100, Trung Quang Nguyen wrote:
> Hi there,
>
> I'm trying to implement Reverse Polish notation calculator from
> learnyouhaskell.com. I want to add one more operator "/", but I cannot
> compile. I comment out the line --func (x:y:ys) "/" = (y / x):ys, thing
> goes well again. Any body knows the cause of this problem?
>
> --rpn.hs
> import System.Environment
> import Data.List
>
> solveRPN :: (Num a, Read a) => String -> a
> solveRPN = head . foldl func [] . words
> where
> func (x:y:ys) "+" = (y + x):ys
> func (x:y:ys) "-" = (y - x):ys
> func (x:y:ys) "*" = (y * x):ys
> --func (x:y:ys) "/" = (y / x):ys
> func xs numStr = read numStr:xs
>
> main = do
> (x:_) <- getArgs
> putStrLn $ show $ solveRPN x
>
> I got this:
> ~/w/r/s/haskell> ghc --make rpn
> [1 of 1] Compiling Main ( rpn.hs, rpn.o )
>
> rpn.hs:5:25:
> Could not deduce (Fractional a) arising from a use of `func'
> from the context (Num a, Read a)
The problem is that you can only use the (/) operator on types which
are instances of the Fractional type class, but you have stated that
your function should work for any type as long as it is an instance of
Num. But being an instance of Num does not imply an instance of
Fractional; your function would not work for any type which is an
instance of Num but not of Fractional, such as Int.
If you only want to use solveRPN with Fractional types like Double or
Rational, you can just change the Num constraint to a Fractional
constraint. If you want solveRPN to work with non-fractional types
like Int, then you have to decide what exactly division is supposed to
mean. Perhaps you want to use 'div' instead of (/) (in which case you
have to use an Integral constraint instead of Num)?
-Brent
------------------------------
Message: 4
Date: Sun, 16 Dec 2012 18:42:26 +0100
From: Daniel Trstenjak <[email protected]>
Subject: Re: [Haskell-beginners] Parsec, comma sperated list with
special last element
To: [email protected]
Message-ID: <20121216174226.GA21528@machine>
Content-Type: text/plain; charset=iso-8859-1
Hi Nathan,
On Sun, Dec 16, 2012 at 05:55:53PM +0100, Nathan H?sken wrote:
> cell = many1 (noneOf ",")
> lastCell = many1 (noneOf "\n")
I wouldn't define the cells by the character that separates them, but
by the allowed characters for a cell.
Using attoparsec with applicative style (I didn't yet use parsec) I would write:
import qualified Data.Attoparsec.Text as P
import qualified Data.Attoparsec.Combinator as PC
import qualified Data.Text as T
import Data.Char (isAlpha)
cell :: P.Parser T.Text
cell = P.takeWhile1 isAlpha
data Row {
fstCell :: T.Text,
sndCell :: T.Text,
lastCell :: T.Text
}
row :: P.Parser Row
row = Row <$> cell
<*> (P.char ',' *> cell)
<*> (P.char ',' *> cell)
rows :: P.Parser [Row]
rows = PC.manyTill row P.endOfLine
The applicative style really shines in these cases, because the
definition of the parser combines nicely with the creation of
the data structures for the parsed data.
Greetings,
Daniel
------------------------------
Message: 5
Date: Sun, 16 Dec 2012 19:26:04 +0100
From: Trung Quang Nguyen <[email protected]>
Subject: Re: [Haskell-beginners] Cannot compile "where" in a function
To: Brent Yorgey <[email protected]>
Cc: beginners <[email protected]>
Message-ID:
<CALs5uBz6QDkAQE=jw9mjubrf6wto2ron9aeqjs6d-s19r4c...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
It works perfectly when I use Fractional with (/) and Integral with (div).
Thanks a lot Brent :)
/Trung
2012/12/16 Brent Yorgey <[email protected]>
> On Sun, Dec 16, 2012 at 06:08:20PM +0100, Trung Quang Nguyen wrote:
> > Hi there,
> >
> > I'm trying to implement Reverse Polish notation calculator from
> > learnyouhaskell.com. I want to add one more operator "/", but I cannot
> > compile. I comment out the line --func (x:y:ys) "/" = (y / x):ys, thing
> > goes well again. Any body knows the cause of this problem?
> >
> > --rpn.hs
> > import System.Environment
> > import Data.List
> >
> > solveRPN :: (Num a, Read a) => String -> a
> > solveRPN = head . foldl func [] . words
> > where
> > func (x:y:ys) "+" = (y + x):ys
> > func (x:y:ys) "-" = (y - x):ys
> > func (x:y:ys) "*" = (y * x):ys
> > --func (x:y:ys) "/" = (y / x):ys
> > func xs numStr = read numStr:xs
> >
> > main = do
> > (x:_) <- getArgs
> > putStrLn $ show $ solveRPN x
> >
> > I got this:
> > ~/w/r/s/haskell> ghc --make rpn
> > [1 of 1] Compiling Main ( rpn.hs, rpn.o )
> >
> > rpn.hs:5:25:
> > Could not deduce (Fractional a) arising from a use of `func'
> > from the context (Num a, Read a)
>
> The problem is that you can only use the (/) operator on types which
> are instances of the Fractional type class, but you have stated that
> your function should work for any type as long as it is an instance of
> Num. But being an instance of Num does not imply an instance of
> Fractional; your function would not work for any type which is an
> instance of Num but not of Fractional, such as Int.
>
> If you only want to use solveRPN with Fractional types like Double or
> Rational, you can just change the Num constraint to a Fractional
> constraint. If you want solveRPN to work with non-fractional types
> like Int, then you have to decide what exactly division is supposed to
> mean. Perhaps you want to use 'div' instead of (/) (in which case you
> have to use an Integral constraint instead of Num)?
>
> -Brent
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
*Trung Nguyen*
Mobile: +45 50 11 10 63
LinkedIn: http://www.linkedin.com/pub/trung-nguyen/36/a44/187
View my blog at http://www.onextrabit.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121216/41a55312/attachment-0001.htm>
------------------------------
Message: 6
Date: Sun, 16 Dec 2012 22:45:41 -0800
From: Karl Voelker <[email protected]>
Subject: Re: [Haskell-beginners] Parsec, comma sperated list with
special last element
To: Nathan H?sken <[email protected]>
Cc: Haskell Beginners <[email protected]>
Message-ID:
<caffow0xd-te3h_hah9dyo7-bw1ujam-jmt4wh9wqfz_kouh...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
On Sun, Dec 16, 2012 at 8:55 AM, Nathan H?sken <[email protected]>wrote:
> I am assuming this is because the lastCell is comsumed by a "cell" parser.
>
Yes. Parsec does not backtrack automatically, which means once the cell
parser has consumed the input that you were hoping would be consumed by
lastCell, your program is never going to go back and reconsider that part
of the input, even if doing so is the only way to make the file parser
succeed.
> lastCell and cell look pretty similar, so the cell parser can does not
> fail when presented the <lastCell>.
>
> Can I still do this with "endBy" or is there a better combinator?
>
Using endBy is not the problem. There are many different solutions:
1. Factor out the common prefix of cell and lastCell, and restructure the
file parser to avoid committing to either cell or lastCell until the next
input symbol is one which definitively identifies which alternative the
parser is looking at.
2. Replace cell and lastCell with a single parser that matches either one.
Parse out a list of cellOrLastCell results and then do some post-processing
to treat the last one specially.
3. Use the "try" combinator. You apply this combinator to a parser, and get
back a parser which consumes no input if it fails. When using this
combinator, you should consider whether this will have an unacceptable
impact on the performance of your parser. (Performance is one of the
reasons Parsec does not just backtrack automatically.)
-Karl
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20121216/98980271/attachment.htm>
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 54, Issue 23
*****************************************