字母P的类型是什么?

时间:2011-04-16 14:44:07

标签: haskell

我对以下程序有一些疑问。

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. 我看不到LetterP的定义,所以我假设它来自导入的包。这是对的吗?

  2. 编译时,我收到错误:

    ho8.hs:19:12: parse error on input `='
    Failed, modules loaded: none.
    

    为什么我会收到此错误,我该如何解决?我试图打印LetterP,但事实并非如此 工作

  3. parens n (term@(LetterP _)) = pp term是什么意思,parens做什么,term@是什么?为什么没有term的定义?

  4. 删除{}后,出现以下错误。为什么呢?

    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.
    

2 个答案:

答案 0 :(得分:4)

LetterPProp类型的数据构造函数。它在代码的以下部分中定义:

data Prop a = 
     LetterP a
   | AndP (Prop a) (Prop a)
 deriving Eq

无法打印,因为它不会导出Show,并且代码中也没有Show (Prop a)的手动实例。但是,您发布的错误是语法错误,与此无关。

(var@pattern)语法用于为模式匹配的值指定名称。因此parens n (term@(LetterP _)) = pp term匹配,如果第二个参数是使用构造函数LetterP的值,并将该值赋给参数term

AndP这样的{p> LetterPProp类型的构造函数。

答案 1 :(得分:1)

LetterP不是类型,它是Prop类型的构造函数,请参阅第8行。

模式语法

name@pattern
如果模式匹配,

将名称绑定到值。因此,在您的情况下,term绑定到函数parens的第二个参数,然后检查此值是否使用LetterP构造。

您得到的错误是因为您无法在do {}块内部编写方程式。你必须在let之前添加它们。

像这样改变

 main = do
    let p = LetterP 1
    print p