Pytałem o tym wcześniej, ale wydaje się, że sformułowałem to pytanie zbyt wąsko. Zobaczmy więc, czy mogę wyjaśnić, po co właściwie jestem.showsPrec i operator precedensy
Załóżmy, że mam typ, który obsługuje kilku operatorów binarnych, z których każdy ma różny priorytet i jest powiązany. Jak napisać instancję Show
, która poprawnie wykonuje podekspozycje?
Wiem, że jestem tutaj gęsty, ale źle to rozumiem za każdym razem Próbuję to zrobić. Musi istnieć jakaś mechaniczna procedura, którą możesz wykonać, aby to poprawnie działało, ale nie mogę go znaleźć. Czy ktoś może przejść przez przykład?
wiem, że to ostatecznie sprowadza się do zawijania wszystko w showParen
i pokazując sub-wyrażeń za pomocą showsPrec
z prawej magicznej liczby, i mogę to zrobić prawie praca, ale to nigdy nie działa prawo w wszystkie okoliczności .
Edit: Rozważmy następujący kod
data Expr =
Const Int |
Expr :+: Expr |
Expr :-: Expr |
Expr :*: Expr |
Expr :/: Expr
infixl 6 :+:
infixl 6 :-:
infixl 7 :*:
infixl 7 :/:
instance Show Expr where
showsPrec p e0 =
case e0 of
Const n -> shows n
x :+: y -> showParen (p > 6) $ (showsPrec 6 x) . (" :+: " ++) . (showsPrec 6 y)
x :-: y -> showParen (p > 6) $ (showsPrec 6 x) . (" :-: " ++) . (showsPrec 6 y)
x :*: y -> showParen (p > 7) $ (showsPrec 7 x) . (" :*: " ++) . (showsPrec 7 y)
x :/: y -> showParen (p > 7) $ (showsPrec 7 x) . (" :/: " ++) . (showsPrec 7 y)
This prawie działa poprawnie:
*Main> Const 1 :+: Const 2 :*: Const 3 :+: Const 4
1 :+: 2 :*: 3 :+: 4
*Main> (Const 1 :+: Const 2) :*: (Const 3 :+: Const 4)
(1 :+: 2) :*: (3 :+: 4)
ale nie całkiem:
*Main> Const 1 :+: Const 2 :-: Const 3 :-: Const 4
1 :+: 2 :-: 3 :-: 4
*Main> Const 1 :+: Const 2 :-: (Const 3 :-: Const 4)
1 :+: 2 :-: 3 :-: 4
Wygląda na to, że pierwszeństwo ma , ale skojarzenie jest zrywane.
Google sugeruje następujące dwa pytania: [Pretty Printing AST z minimalnymi nawiasami] (http: // stackoverflow.com/q/13708837/791604) i [asocjacja i pierwszeństwo wyrażeń podczas generowania kodu C/C++?] (http://stackoverflow.com/q/4306680/791604). Mogą ci dać pewne pomysły. Nie jestem pewien, czy kwalifikuje się to jako duplikat jednego z nich, czy nie, ale na razie skłaniam się ku "nie dup", ponieważ to pytanie jest po części o tym, jak sprawić, aby ogólne techniki pasowały do ekosystemu Haskell. –