How to translate logical notation to Haskell syntax

后端 未结 4 966
天命终不由人
天命终不由人 2021-01-25 13:22

I\'ve recently picked up Haskell at uni and I\'m working my way through a set of exercises, here\'s a snippet of one that I can\'t make sense of:

\"Consider the followin

相关标签:
4条回答
  • 2021-01-25 14:04

    How do I declare type or data(not a variable) for fixed values, namely 0-9?

    You can define a type, like

    data Digit = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine deriving (Eq, Show)
    

    This represents the num in your problem. Obviously we cannot use 0, 1, 2, 3, ... since they are already interpreted as numbers in Haskell.

    Then, you can define

    data Number = Single Digit | Many Digit Number deriving (Eq, Show)
    

    which is equivalent to int in your problem. This type represents one (Single ...) or more (Many ...) digits, which together make a one decimal number. For example, with these data types a number 361 would be Many Three (Many Six (Single One)).

    Also, how can I put symbols like - or + in a declaration?

    There is no way to put those symbols in type or data declarations. You can use, however, names for the operations, like Sum, Sub and Mul. Then the expr of the grammar of your problem would translate to

    data Expr   = Lit Number
                | Sub Expr Expr
                | Sum Expr Expr
                | Mul Expr Expr
                deriving (Eq, Show)
    

    If we would have a string "+ (- (2 5) (1 3)) 3", which represents an expression in the prefix calculator language of your problem , it would be parsed to Sum (Sub (Lit (Many Two (Single Five))) (Lit (Many One (Single Three)))) (Single Three).

    0 讨论(0)
  • 2021-01-25 14:09

    Don't confuse a string in the grammar for the AST that represents it. Compare the string

    "+ + 3 4 5"
    

    which is a string in the grammar you've been given with

    Plus (Plus (Literal 3) (Literal 4)) (Literal 5)
    

    which would be a sensible Haskell value for the AST that String could get parsed to.

    0 讨论(0)
  • 2021-01-25 14:14

    If it is just a exercise about modeling data (without code) the answer consist of adding constructor names to your grammar (and changing literal number to names). Something like

    data Num = Zero | One | Two | Three | Four | Five 
             | Six | Seven | Eight | Nine
    data Int = Single Num | Multiple Num Int
    data Exp = ExpInt Int | ExpMinus Exp Exp | ExpMul Exp Exp
             | ExpMul Exp Exp
    

    From that, you can write all sort of code, to parse and evaluate expressions.

    0 讨论(0)
  • 2021-01-25 14:16

    Years ago, I got clever, and I declared my AST type an instance of Num, Eq and Ord, then defined the mathematical and comparison operators for AST expressions, so that expr1 + expr2 would yield a valid AST. Using sevenj’s declarations, this would be written like (+) x y = Sum x y, where the right-hand side is the constructor of an AST expression. For brevity, one = Lit One and two = Lit Two. Then you might write one + one == two and the operators would generate your AST with the correct precedence. Between that and abuse of the let { ... } in ... syntax to allow for arbitrary indentation, I had a way to write ASTs that was almost just the toy imperative language itself, with some boilerplate above, below and on the left.

    The TA grading my assignment, though, was not amused, and wrote, “This is not Haskell!”

    0 讨论(0)
提交回复
热议问题