# 03-Multiply.purs

``````module Free.ExpressionBased.VariantF.Multiply where

import Effect (Effect)
import Effect.Console (log)
import Data.Functor.Variant (VariantF, inj, on)
import Type.Row (type (+))
import Type.Proxy (Proxy(..))
import Free.ExpressionBased.VariantF.Value (
Value, value
, example_value, valueAlgebra

, Expression(..), eval
)

)

-- data stuff
data MultiplyF e = MultiplyF e e
derive instance Functor MultiplyF

-- VariantF stuff
type Multiply r = (multiply :: MultiplyF | r)

multiplySymbol :: Proxy "multiply"
multiplySymbol = Proxy

multiply :: forall r
. Expression (VariantF (Multiply + r))
-> Expression (VariantF (Multiply + r))
-> Expression (VariantF (Multiply + r))
multiply x y = In \$ inj multiplySymbol (MultiplyF x y)

-- eval stuff
multiplyAlgebra :: forall r
. (VariantF r Int -> Int)
-> (VariantF (Multiply + r) Int -> Int)
multiplyAlgebra =
on multiplySymbol (\(MultiplyF x y) -> x * y)

-- Composition: Exclude Add - Only Value & Multiply
vmAlgebra :: forall r
. (VariantF r Int -> Int)
-> (VariantF (Value + Multiply + r) Int -> Int)
vmAlgebra =
valueAlgebra >>> multiplyAlgebra

example_value_multiply :: forall r. Expression (VariantF (Value + Multiply + r))
example_value_multiply =
multiply (value 5) (multiply (value 3) (value 6))

-- Composition: Value, Add, & Multiply
vamAlgebraComposed :: forall r
. (VariantF r Int -> Int)
-> (VariantF (Value + Add + Multiply + r) Int -> Int)
vamAlgebraComposed =

-- This approach is not as refactor-resistant
-- to the algebra immediately above
vamAlgebraShorter :: forall r
. (VariantF r Int -> Int)
-> (VariantF (VA + Multiply + r) Int -> Int)
vamAlgebraShorter = vaAlgebraComposed >>> multiplyAlgebra

example_value_add_multiply :: forall r. Expression (VariantF (VA + Multiply + r))
(multiply
example_value
(value 8)
)
(multiply
example_value_multiply