我对以下程序有一些疑问。
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
我看不到LetterP
的定义,所以我假设它来自导入的包。这是对的吗?
编译时,我收到错误:
ho8.hs:19:12: parse error on input `='
Failed, modules loaded: none.
为什么我会收到此错误,我该如何解决?我试图打印LetterP
,但事实并非如此
工作
parens n (term@(LetterP _)) = pp term
是什么意思,parens
做什么,term@
是什么?为什么没有term
的定义?
删除{}
后,出现以下错误。为什么呢?
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 :(得分:4)
LetterP
是Prop
类型的数据构造函数。它在代码的以下部分中定义:
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> LetterP
是Prop
类型的构造函数。
答案 1 :(得分:1)
LetterP
不是类型,它是Prop
类型的构造函数,请参阅第8行。
模式语法
name@pattern
如果模式匹配,将名称绑定到值。因此,在您的情况下,term
绑定到函数parens
的第二个参数,然后检查此值是否使用LetterP
构造。
您得到的错误是因为您无法在do {}块内部编写方程式。你必须在let之前添加它们。
像这样改变
main = do
let p = LetterP 1
print p