I have some questions about the following program.
import Data.List(nub)
import qualified Text.PrettyPrint.HughesPJ as PP
import Text.PrettyPrint开发者_开发百科.HughesPJ(Doc,text,int,(<>),(<+>),($+$),render)
data Prop a =
LetterP a
| AndP (Prop a) (Prop a)
deriving Eq
class PPLetter a where
ppLetter :: a -> Doc
instance PPLetter Int where
ppLetter a = text ("p"++show a)
instance PPLetter Char where
ppLetter = PP.char
instance PPLetter a => PPLetter [a] where
ppLetter = PP.hcat . (map ppLetter)
class PP a where
pp :: a -> Doc
instance PP Bool where
pp True = text "True"
pp False = text "False"
parens n (term@(LetterP _)) = pp term
instance PPLetter a => PP(Prop a) where
pp (LetterP a) = ppLetter a
pp (AndP x y) = PP.sep [ parens 4 x, text "/\\", parens 4 y]
instance PPLetter a => Show (Prop a) where
show x = render (pp x)
main = do
let p = LetterP 1
print p
I can't see a definition of
LetterP
, so I assume it is from an imported package. Is that correct?When I compile it, I get an error:
ho8.hs:19:12: parse error on input `=' Failed, modules loaded: none.
why do I get this error, and how do I solve it? I tried to print
LetterP
but it didn't work.What does
parens n (term@(LetterP _)) = pp term
mean, what doparens
do and what isterm@
? Why is there no definition ofterm
?After removing
{}
, I get the following error. Why?ho8.hs:43:9: Ambiguous type variable `a0' in the constraints: (PPLetter a0) arising from a use of `print' at ho8.hs:43:9-13 (Num a0) arising from the literal `1' at ho8.hs:42:25 Probable fix: add a type signature that fixes these type variable(s) In the expression: print p In the expression: do { let p = LetterP 1; print p } In an equation for `main': main = do { let p = ...; print p } Failed, modules loaded: none.
LetterP
is a data constructor for the type Prop
. It is defined in the following part of your code:
data Prop a =
LetterP a
| AndP (Prop a) (Prop a)
deriving Eq
It can not be printed because it does not derive Show
and there is also no manual instance for Show (Prop a)
in your code. However the error you posted is a syntax error and not related to that.
The (var@pattern)
syntax is used to give a name to the value matched by the pattern. So parens n (term@(LetterP _)) = pp term
matches if the second argument is a value using the constructor LetterP
and assigns that value to the argument term
.
AndP
like LetterP
is a constructor for the type Prop
.
LetterP
is not a type, it's a constructor of type Prop
, see line 8.
The pattern syntax
name@pattern
binds name to the value if the pattern matches. Thus in your case, term
is bound to the 2nd argument of function parens
and then it is checked if this value was constructed with LetterP
.
The error you get is because you can't write equations inside do { } blocks. You must prepend them with let.
Change it like so
main = do
let p = LetterP 1
print p
精彩评论