Skip to content

Instantly share code, notes, and snippets.

@Lysxia
Created October 3, 2022 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lysxia/75e45d89338e44d527224fa78aeec37b to your computer and use it in GitHub Desktop.
Save Lysxia/75e45d89338e44d527224fa78aeec37b to your computer and use it in GitHub Desktop.
{-# LANGUAGE DataKinds, TypeFamilies, TypeOperators #-}
module D where
import Control.Applicative (liftA2)
import Data.Kind (Type)
data F = VALUE | F :-> F
infixr 1 :->
type family Unquote (t :: F) :: Type where
Unquote VALUE = Value
Unquote (t :-> t') = Unquote t -> Unquote t'
data Value
data Expr a = Closed (Unquote a) | Open (Expr (VALUE :-> a))
mapExpr :: (Unquote a -> Unquote b) -> Expr a -> Expr b
mapExpr f (Closed x) = Closed (f x)
mapExpr f (Open y) = Open (mapExpr (fmap f) y)
pureExpr :: Unquote a -> Expr a
pureExpr = Closed
liftA2Expr :: Unquote (a :-> b :-> c) -> Expr a -> Expr b -> Expr c
liftA2Expr f (Closed x) y = mapExpr (f x) y
liftA2Expr f x (Closed y) = mapExpr (flip f y) x
liftA2Expr f (Open x) (Open y) = Open (liftA2Expr (liftA2 f) x y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment