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. Design questions for a Pascal interpreter (Giuliano Vilela)
2. Re: Design questions for a Pascal interpreter ([email protected])
3. Re: Parsec 3.0 problems (Philippa Cowderoy)
4. typeclass error (Amitava Shee)
5. Re: typeclass error (Joe Fredette)
6. Re: typeclass error (Quentin Moser)
7. Re: typeclass error (Amitava Shee)
8. Re: typeclass error (Joe Fredette)
----------------------------------------------------------------------
Message: 1
Date: Mon, 20 Apr 2009 20:28:44 -0300
From: Giuliano Vilela <[email protected]>
Subject: [Haskell-beginners] Design questions for a Pascal interpreter
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hello,
I've been doing some research for a upcoming homework project, a
Pascal interpreter written in Haskell. As a beginner to the language,
I have a few design questions I'd like to share with you.
I started playing with Parsec, getting a feel for parsing with monadic
combinators. My assumption here is that i'm going to take the source,
transform it in an AST (built with normal data constructors present in
Haskell), maybe build a symbol table while doing that (using the
implicity state in Parsec), do some checking (mainly type checking I
think), and the evaluation itself.
Here are a few questions I had so far:
- Keeping the whole AST in memory for the evalution phase seems
overkill. Is there a better way?
- The evalution, I think, would be a set of nice pure mutually
recursive functions that do some pattern matching on the program AST.
I would pass the current stack and heap for those functions to use and
modify. Is the State monad a good fit for this task? Wouldn't the code
become "too imperative"?
- And finally, the big question. Consider the following pascal source:
program HelloWorld;
begin
writeln('Hello World');
end.
To evaluate the AST, I would eventually arrive at something like:
eval (FunctionCall func_name func_args) = ...
Obviously, to evaluate writeln I need to be in the IO monad. Here, my
whole scheme went down. Do I really have to mix my own state (stack,
heap) within the IO monad along my evaluation functions?
PS: I could keep a list of things to print, that I would eventually do
after I traversed the whole tree, but that wouldn't be "realistic".
Thank you!
--
[]'s
Giuliano Vilela.
------------------------------
Message: 2
Date: Mon, 20 Apr 2009 20:14:01 -0400
From: [email protected]
Subject: Re: [Haskell-beginners] Design questions for a Pascal
interpreter
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes";
format="flowed"
G'day all.
Quoting Giuliano Vilela <[email protected]>:
> - Keeping the whole AST in memory for the evalution phase seems
> overkill. Is there a better way?
In this day and age, it's not considered overkill to keep an entire
program in memory in a tree form. Perl 5 does that, for example.
However, Pascal is simple enough that it can be translated from
within the parser. Quite a few influential Pascal compilers,
including the simplest ones such as Pascal-P and Pascal-S, and some
not-so-simple ones such as Turbo Pascal, did not even generate an AST,
but compiled straight to P-code or assembly code from within the parser.
> - The evalution, I think, would be a set of nice pure mutually
> recursive functions that do some pattern matching on the program AST.
> I would pass the current stack and heap for those functions to use and
> modify. Is the State monad a good fit for this task? Wouldn't the code
> become "too imperative"?
Interpretation of an imperative language is imperative. I wouldn't
worry about it.
You will probably end up using a few monad transformers, because you
need to need at least I/O and a heap, and quite possibly a symbol
table as well.
> Obviously, to evaluate writeln I need to be in the IO monad. Here, my
> whole scheme went down. Do I really have to mix my own state (stack,
> heap) within the IO monad along my evaluation functions?
You really need to learn about monad transformers. Try this for
starters:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.17.268
Good luck, and let us know how you go.
Cheers,
Andrew Bromage
------------------------------
Message: 3
Date: Tue, 21 Apr 2009 03:17:50 +0100
From: Philippa Cowderoy <[email protected]>
Subject: Re: [Haskell-beginners] Parsec 3.0 problems
To: Ian Duncan <[email protected]>
Cc: [email protected]
Message-ID: <1240280270.9080.5.ca...@flippa-eee>
Content-Type: text/plain
On Mon, 2009-04-20 at 18:26 -0500, Ian Duncan wrote:
> No instance for (Stream s m Char)
> arising from a use of `spaces' at tree.hs:18:32-37
> Possible fix: add an instance declaration for (Stream s m Char)
> In the first argument of `between', namely `spaces'
> In the second argument of `(<$>)', namely
> `(between spaces (char ':') (many1 alphaNum))'
> In the expression:
> Label <$> (between spaces (char ':') (many1 alphaNum))
>
>
> When I test this function in ghci, I have no problems, yet whenever I
> try to open it in a file it fails. What am I doing wrong?
Looks like you're getting bitten by the monomorphism restriction. {-#
LANGUAGE NoMonomorphismRestriction #-} at the top of the source file to
make it go away.
The MR is a real usability problem for Parsec 3, sadly :-( You may find
it easier to work with the latest version of Parsec 2, which is still
the recommended version for most purposes.
--
Philippa Cowderoy <[email protected]>
------------------------------
Message: 4
Date: Tue, 21 Apr 2009 09:27:57 -0400
From: Amitava Shee <[email protected]>
Subject: [Haskell-beginners] typeclass error
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
I have the following code
-- foo.hs
module Foo where
class Foo a where
bar :: a -> a
instance Foo Int where
bar i = i + 10
------------------
It fails to compile withe following error
*Foo> bar 10
<interactive>:1:4:
Ambiguous type variable `t' in the constraints:
`Num t' arising from the literal `10' at <interactive>:1:4-5
`Foo t' arising from a use of `bar' at <interactive>:1:0-5
Probable fix: add a type signature that fixes these type variable(s)
*Foo>
- Thanks
Amitava Shee
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20090421/e448181f/attachment-0001.htm
------------------------------
Message: 5
Date: Tue, 21 Apr 2009 09:42:15 -0400
From: Joe Fredette <[email protected]>
Subject: Re: [Haskell-beginners] typeclass error
To: Amitava Shee <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
If I'm not mistaken, changing:
bar i = i + 10
to
bar i = i + 10::Int
ought to fix it.
The issue is that the compiler is being to general wrt the type of "10",
it's inferring that it's just of type (Num a => a) -- the type of all
numbers (sortof.)
Alternately, you could implement this as:
instance Num a => Foo a where
bar x = x + 10
which similarly ought to fix it. Do you understand why?
Amitava Shee wrote:
> I have the following code
>
> -- foo.hs
> module Foo where
>
> class Foo a where
> bar :: a -> a
>
> instance Foo Int where
> bar i = i + 10
>
> ------------------
>
> It fails to compile withe following error
> *Foo> bar 10
>
> <interactive>:1:4:
> Ambiguous type variable `t' in the constraints:
> `Num t' arising from the literal `10' at <interactive>:1:4-5
> `Foo t' arising from a use of `bar' at <interactive>:1:0-5
> Probable fix: add a type signature that fixes these type variable(s)
> *Foo>
>
> - Thanks
> Amitava Shee
> ------------------------------------------------------------------------
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jfredett.vcf
Type: text/x-vcard
Size: 296 bytes
Desc: not available
Url :
http://www.haskell.org/pipermail/beginners/attachments/20090421/be3b36aa/jfredett-0001.vcf
------------------------------
Message: 6
Date: Tue, 21 Apr 2009 16:02:55 +0200
From: Quentin Moser <[email protected]>
Subject: Re: [Haskell-beginners] typeclass error
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Tue, 21 Apr 2009 09:27:57 -0400
Amitava Shee <[email protected]> wrote:
> I have the following code
>
> -- foo.hs
> module Foo where
>
> class Foo a where
> bar :: a -> a
>
> instance Foo Int where
> bar i = i + 10
>
> ------------------
>
> It fails to compile withe following error
> *Foo> bar 10
>
> <interactive>:1:4:
> Ambiguous type variable `t' in the constraints:
> `Num t' arising from the literal `10' at <interactive>:1:4-5
> `Foo t' arising from a use of `bar' at <interactive>:1:0-5
> Probable fix: add a type signature that fixes these type
> variable(s) *Foo>
>
When you type an expression into GHCi, it needs to be able to assign
it a monomorphic type (a type without variables) in order to know
which "show" to use on it to print it. From the types of bar (Foo a =>
a -> a) and 10 (Num a => a), GHCi can only deduce that bar 10 should
have type ((Foo a, Num a) => a). It's also not smart enough to notice that
there's only one type that's an instance of both Foo and Bar, and use
it.
Your declarations are perfectly fine, but there's not enough information
at the call site of bar to pin it down to a particular type. It can be
solved simply by adding a type signature there (bar 10 :: Int).
Note also that, since numeric code is common and uses a lot of type
classes, Haskell has ad-hoc defaulting rules for it: When there's an
ambiguity on the type of a variable and at least one of its class
constraints is numeric (e.g. Num or Integral), the compiler will try to
use a default type. Unfortunately the default Num type is Integer
which isn't an instance of Foo, so the defaulting rules don't apply in
your case.
------------------------------
Message: 7
Date: Tue, 21 Apr 2009 11:21:11 -0400
From: Amitava Shee <[email protected]>
Subject: Re: [Haskell-beginners] typeclass error
To: Joe Fredette <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Thank you.
I get the following error after making the suggested changes
-- foo.hs
{-# LANGUAGE FlexibleInstances #-}
module Foo where
class Foo a where
bar :: a -> a
--
-- instance Foo Int where
-- bar i = i + 10
--
-- instance Foo [Char] where
-- bar m = "foo" ++ m
--
instance Num a => Foo a where
bar x = x + 10
-----
foo.hs:14:0:
Constraint is no smaller than the instance head
in the constraint: Num a
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Foo a'
Failed, modules loaded: none.
Prelude>
...Amitava
On Tue, Apr 21, 2009 at 9:42 AM, Joe Fredette <[email protected]> wrote:
> If I'm not mistaken, changing:
>
> bar i = i + 10
>
> to
>
> bar i = i + 10::Int
>
> ought to fix it.
>
> The issue is that the compiler is being to general wrt the type of "10",
> it's inferring that it's just of type (Num a => a) -- the type of all
> numbers (sortof.)
>
> Alternately, you could implement this as:
>
> instance Num a => Foo a where
> bar x = x + 10
>
> which similarly ought to fix it. Do you understand why?
>
> Amitava Shee wrote:
>
>> I have the following code
>>
>> -- foo.hs
>> module Foo where
>>
>> class Foo a where
>> bar :: a -> a
>> instance Foo Int where
>> bar i = i + 10
>> ------------------
>>
>> It fails to compile withe following error
>> *Foo> bar 10
>>
>> <interactive>:1:4:
>> Ambiguous type variable `t' in the constraints:
>> `Num t' arising from the literal `10' at <interactive>:1:4-5
>> `Foo t' arising from a use of `bar' at <interactive>:1:0-5
>> Probable fix: add a type signature that fixes these type variable(s)
>> *Foo>
>>
>> - Thanks
>> Amitava Shee
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> 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/20090421/29e865ab/attachment-0001.htm
------------------------------
Message: 8
Date: Tue, 21 Apr 2009 12:44:06 -0400
From: Joe Fredette <[email protected]>
Subject: Re: [Haskell-beginners] typeclass error
To: Amitava Shee <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Right, I was incorrect, you should use the solution that Quentin gave-
to recap it,
The basic problem is that GHCi is trying to infer a single type --
called "monomorphic" -- for your more general type.
the type of `bar` is `Foo a => a -> a`, when ghci looks at a literal
number (like 10) it interprets it as a "default" type of
Integer (not int). Since Integer does not instance Foo, then GHCi yells
at you.
Quentin explained it far better than I, I refer you to his email.
/Joe
Amitava Shee wrote:
> Thank you.
>
> I get the following error after making the suggested changes
>
> -- foo.hs
> {-# LANGUAGE FlexibleInstances #-}
> module Foo where
>
> class Foo a where
> bar :: a -> a
> --
> -- instance Foo Int where
> -- bar i = i + 10
> --
> -- instance Foo [Char] where
> -- bar m = "foo" ++ m
> --
>
> instance Num a => Foo a where
> bar x = x + 10
>
> -----
>
> foo.hs:14:0:
> Constraint is no smaller than the instance head
> in the constraint: Num a
> (Use -XUndecidableInstances to permit this)
> In the instance declaration for `Foo a'
> Failed, modules loaded: none.
> Prelude>
>
> ...Amitava
>
> On Tue, Apr 21, 2009 at 9:42 AM, Joe Fredette <[email protected]
> <mailto:[email protected]>> wrote:
>
> If I'm not mistaken, changing:
>
> bar i = i + 10
>
> to
>
> bar i = i + 10::Int
>
> ought to fix it.
>
> The issue is that the compiler is being to general wrt the type of
> "10", it's inferring that it's just of type (Num a => a) -- the
> type of all numbers (sortof.)
>
> Alternately, you could implement this as:
>
> instance Num a => Foo a where
> bar x = x + 10
>
> which similarly ought to fix it. Do you understand why?
>
> Amitava Shee wrote:
>
> I have the following code
>
> -- foo.hs
> module Foo where
>
> class Foo a where
> bar :: a -> a
> instance Foo Int where
> bar i = i + 10
> ------------------
>
> It fails to compile withe following error
> *Foo> bar 10
>
> <interactive>:1:4:
> Ambiguous type variable `t' in the constraints:
> `Num t' arising from the literal `10' at <interactive>:1:4-5
> `Foo t' arising from a use of `bar' at <interactive>:1:0-5
> Probable fix: add a type signature that fixes these type
> variable(s)
> *Foo>
>
> - Thanks
> Amitava Shee
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Beginners mailing list
> [email protected] <mailto:[email protected]>
> http://www.haskell.org/mailman/listinfo/beginners
>
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jfredett.vcf
Type: text/x-vcard
Size: 296 bytes
Desc: not available
Url :
http://www.haskell.org/pipermail/beginners/attachments/20090421/b856729c/jfredett.vcf
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 10, Issue 19
*****************************************