Jog*_*ger 5 syntax haskell boilerplate recursion-schemes
使用递归方案库,可以轻松编写抽象语法树和相应的表达式计算器:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE LambdaCase #-}
import Data.Functor.Foldable
import Data.Functor.Foldable.TH
data Expr = Plus Expr Expr
| Mult Expr Expr
| Const Expr
deriving (Show, Eq)
makeBaseFunctor ''Expr
-- Write a simple evaluator
eval :: Expr -> Int
eval = cata alg
where
alg = \case
PlusF x y -> (+) x y
MultF x y -> (*) x y
ConstF x -> x
Run Code Online (Sandbox Code Playgroud)
现在看看algwhere子句中函数的情况eval.我认为所有x和y变量都不是必需的.因此,我正在寻找一些方法(语法,语言扩展等)来删除这个样板并只写:
PlusF -> (+)
MultF -> (*)
ConstF -> id
Run Code Online (Sandbox Code Playgroud)
或者,您可以重构您的语言,一方面进行二进制操作,另一方面进行一元操作。你会写:
data BinOp = PlusOp | MultOp deriving (Show, Eq)
data UnOp = ConstOp deriving (Show, Eq)
data Expr = Bin BinOp Expr Expr
| Un UnOp Expr
deriving (Show, Eq)
makeBaseFunctor ''Expr
Run Code Online (Sandbox Code Playgroud)
评估者则变为:
eval :: Expr -> Int
eval = cata $ \case
BinF op l r -> bin op l r
UnF op v -> un op v
where
bin = \case
PlusOp -> (+)
MultOp -> (*)
un = \case
ConstOp -> id
Run Code Online (Sandbox Code Playgroud)