data Expr = Var Char | Not Expr | And Expr Expr | Or Expr Expr deriving (Eq, Ord)
instance Show Expr where
show (Var x) = [x]
show (Not (Var y)) = "~" show (Var y)
show (And (Var x) (Var y)) = show (Var x) " ^ " show (Var y)
show ((Or (Var x) (Var y))) = show (Var x) " v " show (Var y)
show (Not (Or (Var x) (Var y))) = "~(" show (Or (Var x) (Var y)) ")"
show (And (Var x) (And (Var y) (Var z))) = show (Var x) " ^ " "(" show (And (Var y) (Var z)) ")"
我不確定為什么我在運行時會收到此錯誤:
>(Not (Not (Var 'a')))
*** Exception: (21,5)-(26,112): Non-exhaustive patterns in function show
誰能幫我。
uj5u.com熱心網友回復:
一個And也可以包含另一個And,例如And (And (Var 'x') (Var 'y')) (Var 'z')。在您的Show實體中,您始終假設引數為Vars,這是不必要的。
您可以將Show實體實作為:
instance Show Expr where
show (Var x) = [x]
show (Not x) = "~ (" show x ")"
show (And x y) = "(" show x " ^ " show y ")"
show (Or x y) = "(" show x " v " show y ")"
這會引入很多括號。因此最好使用優先引數。事實上,該Show實體已經對此提供了支持:您可以使用showsPrec :: Int -> a -> String -> String. 這里的Int引數是外部背景關系的運算子優先級,第一個String引數是需要在末尾附加的字串:這是出于性能原因而完成的。
因此,我們可以將其實作為:
instance Show Expr where
showsPrec n (Var x) = (x :)
showsPrec n (Not x) = showParen (n > 9) ( ('~' :) . showsPrec 10 x)
showsPrec n (And x y) = showParen (n > 8) ((showsPrec 9 x) . (" ^ " ) . showsPrec 9 y)
showsPrec n (Or x y) = showParen (n > 7) ((showsPrec 8 x) . (" v " ) . showsPrec 8 y)
在這里,我們將顯示括號,not如果外部 countext 的優先級高于9,并呼叫優先級showPrec為 10 的 ,這樣showPrec內部就不會列印額外的括號,除非它的優先級為 10 或更高。這同樣適用于其他功能。
這意味著我們可以列印一個帶括號的運算式,如:
ghci> show (Not (And (Or (Not (Var 'x')) (Var 'y')) (Var 'z')))
"~((~x v y) ^ z)"
這里And … …將因此列印括號,因為它以 9 的優先級呼叫,并且列印括號的閾值為 8。但是 around 沒有括號~x,因為閾值低于 10。
uj5u.com熱心網友回復:
您應該只對最頂層的建構式進行模式匹配,然后向下遞回,而不是對大量深層運算式進行硬編碼。
instance Show Expr where
show (Var v) = [v]
show (Not x) = "Not (" show x ")"
show (And x y) = "(" show x ") ∧ (" ...
show (Or x y) = ...
記住要落實∧和∨如果在提到這些運營商show的結果。
infixr 3 ∧
(∧) :: Expr -> Expr -> Expr
(∧) = And
實際上,在定義遞回資料實體時最好不要實作,而是實作具有更復雜的根據需要添加括號的方法。showShowshowsPrec
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/394433.html
標籤:哈斯克尔
上一篇:來自Test.QuickCheck的Args中的maxSize欄位描述了什么?
下一篇:index.esm2017.js:370Uncaught(inpromise)FirebaseError:ReactJs中的權限缺失或不足
