Я только начинаю с шаблона haskell.
Я написал функцию, которая принимает функцию a -> [b]
и генерирует выражение для функции b -> a
:
{-# OPTIONS_GHC -Wall -Wextra -Werror #-}
module Surjection where
import Language.Haskell.TH
import Data.Traversable
surj :: (Show a, Show b, Bounded a, Enum a) => (a -> [b]) -> Q Exp -- Q (TExp (b -> a))
surj f = fmap (LamCaseE . concat) . -- \case
forM [minBound .. maxBound] $ \a -> do
Just aName <- lookupValueName (show a)
forM (f a) $ \b -> do
Just bName <- lookupValueName (show b)
return $ Match (ConP bName []) (NormalB (ConE aName)) [] -- $(bName) -> $(aName)
Это работает, но было бы неплохо, если бы я мог пообещать, что он возвращает функцию такого типа, то есть он возвращает Q (TExp (b -> a))
, а не Q Exp
.
Все, что я До сих пор мы видели, что для генерации типизированных выражений используются сплайсы и квазицитаты. Есть ли способ сгенерировать его из шаблонных haskell конструкторов?