2011-01-17 15 views
11

Sono nuovo di Haskell e sto cercando di analizzare le espressioni. Ho scoperto di Parsec e ho anche trovato alcuni articoli, ma non riesco a capire cosa devo fare. Il mio problema è che voglio dare un'espressione come "x^2 + 2 * x + 3" e il risultato è una funzione che accetta un argomento x e restituisce un valore. Mi dispiace molto se questa è una domanda facile ma ho davvero bisogno di aiuto. Grazie! Il codice che ho inserito è tratto dall'articolo che puoi trovare su this link.Funzione di analisi in haskell

import Control.Monad(liftM) 
import Text.ParserCombinators.Parsec 
import Text.ParserCombinators.Parsec.Expr 
import Text.ParserCombinators.Parsec.Token 
import Text.ParserCombinators.Parsec.Language 

data Expr = Num Int  | Var String | Add Expr Expr 
      | Sub Expr Expr | Mul Expr Expr | Div Expr Expr 
      | Pow Expr Expr 
      deriving Show 

expr :: Parser Expr 
expr = buildExpressionParser table factor 
    <?> "expression" 

table = [[op "^" Pow AssocRight], 
     [op "*" Mul AssocLeft, op "/" Div AssocLeft], 
     [op "+" Add AssocLeft, op "-" Sub AssocLeft]] 
    where 
     op s f assoc 
      = Infix (do{ string s; return f}) assoc 
factor = do{ char '(' 
     ; x <- expr 
     ; char ')' 
     ; return x} 
    <|> number 
    <|> variable 
    <?> "simple expression" 

number :: Parser Expr 
number = do{ ds<- many1 digit 
     ; return (Num (read ds))} 
    <?> "number" 

variable :: Parser Expr 
variable = do{ ds<- many1 letter 
     ; return (Var ds)} 
    <?> "variable" 
+0

Ho qualcosa che ho trovato in alcuni articoli ma è giusto pubblicarlo anche se non è il mio? – izayoi

+0

si prega di postarlo come altri possono trovare utile pure. Assicurati di includere un link alla fonte originale. –

risposta

13

Questo è solo un parser per espressioni con variabili. In realtà interpretare l'espressione è una questione completamente separata.

È necessario creare una funzione che accetta un'espressione già analizzata e valori per le variabili e restituisce il risultato della valutazione dell'espressione. Pseudocodice:

evaluate :: Expr -> Map String Int -> Int 
evaluate (Num n) _ = n 
evaluate (Var x) vars = {- Look up the value of x in vars -} 
evaluate (Plus e f) vars = {- Evaluate e and f, and return their sum -} 
... 

Ho omesso deliberatamente alcuni dettagli; eventualmente esplorando le parti mancanti, si impara di più su Haskell.

Come passo successivo, probabilmente si dovrebbe guardare il Reader Monade di un modo conveniente per passare la mappa variabile vars intorno, e l'utilizzo di Maybe o Error per segnalare errori, per esempio referenziare una variabile che non è associata a vars o divisione per zero.