开发者

what is the type of LetterP?

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
  1. I can't see a definition of LetterP, so I assume it is from an imported package. Is that correct?

  2. 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.

  3. What does parens n (term@(LetterP _)) = pp term mean, what do parens do and what is term@? Why is there no definition of term?

  4. 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜