2011-04-16 112 views
1

我對以下程序有一些疑問。LetterP的類型是什麼?

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 ([email protected](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 ([email protected](LetterP _)) = pp term是什麼意思,parens是做什麼和[email protected]是做什麼的?爲什麼沒有定義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. 
    
+0

它是否適用於'(1 :: Int)' – Ingo 2011-04-16 16:39:49

回答

4

LetterP是該類型Prop數據構造。它是在你的代碼的以下部分定義:

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

它不能打印,因爲它沒有得到Show有也是在你的代碼Show (Prop a)沒有手動實例。但是,您發佈的錯誤是語法錯誤,與此無關。

([email protected])語法用於給出與該模式匹配的值的名稱。因此,如果第二個參數是使用構造函數LetterP的值,並且將該值分配給參數term,則parens n ([email protected](LetterP _)) = pp term匹配。

AndP like LetterP是類型Prop的構造函數。

+0

這些構造函數做什麼? – Jo0o0 2011-04-16 15:08:31

+0

@MFLDSH:它構造'Prop'類型的值。欲瞭解更多信息,請參閱[維基百科關於代數數據類型的文章](http://en.wikipedia.org/wiki/Algebraic_data_type)。 – sepp2k 2011-04-16 16:25:59

1

LetterP不是一個類型,它的Prop類型的構造,參見線8

圖案語法

[email protected] 

結合名稱到值,如果模式匹配。因此在你的情況下,term綁定到函數parens的第二個參數,然後檢查這個值是否使用LetterP構造。

您得到的錯誤是因爲您無法在do {}塊內寫入方程式。你必須先讓它們放在一邊。

更改它像這樣

main = do 
    let p = LetterP 1 
    print p 
+0

這個構造函數是做什麼的? – Jo0o0 2011-04-16 15:28:40

+0

它構造了一個'Prop'類型的值。它可以被看作是一個函數,它接受任何類型的值'a'並返回一個類型爲'Prop a'的值。 – Ingo 2011-04-16 15:53:52

+3

我想知道你可能會錯過它,它是在你的代碼的第8行中定義的。或者那不是你的代碼? – Ingo 2011-04-16 15:55:00