У меня есть функция, которая по заданной Name
функции она дополняющая ее, получая еще одну функции, применяемой к какому-либо другому материалу (подробности не очень уместно):Шаблон Haskell: Как извлечь количество аргументов функции?
mkSimple :: Name -> Int -> Q [Dec]
mkSimple adapteeName argsNum = do
adapterName <- newName ("sfml" ++ (capitalize . nameBase $ adapteeName))
adapteeFn <- varE adapteeName
let args = mkArgs argsNum
let wrapper = mkApply adapteeFn (map VarE args)
-- generates something like SFML $ liftIO $ ((f a) b) c)
fnBody <- [| SFML $ liftIO $ $(return wrapper) |]
return [FunD adapterName [Clause (map VarP args) (NormalB fnBody) []]]
where
mkArgs :: Int -> [Name]
mkArgs n = map (mkName . (:[])) . take n $ ['a' .. 'z']
-- Given f and its args (e.g. x y z) builds ((f x) y) z)
mkApply :: Exp -> [Exp] -> Exp
mkApply fn [] = fn
mkApply fn (x:xs) = foldr (\ e acc -> AppE acc e) (AppE fn x) xs
Это работает, но это утомительно, чтобы пройти внешнее число аргументов, функция адаптирования имеет. Существует некоторая функция TH для извлечения числа аргументов? Я подозреваю, что это может быть достигнуто с reify, но я не знаю как.
Спасибо!
достаточно просто, несмотря на то, извлекая количество стрелок кажется громоздким и вовлекая много шаблонов матчей. Это можно сделать рекурсивным, но я не вижу простой базовый регистр для рекурсии. Есть идеи? Очевидно, что-то вроде T.count «ArrowT» (show t) подвержено ошибкам (например, если у вас есть :: (a -> b) -> c -> d, счет будет неправильным) –
@AlfredoDiNapoli жаль, что ленился с ' countTheTopLevelArrowTs' в моем ответе. Это действительно громоздко, но не должно быть двусмысленным: обратите внимание, что вам не нужно рекогносцировать первые аргументы любого из «ArrowT». Я обновлю свой ответ. – jberryman
Это неоднозначно. Сколько аргументов в функция с подписью 'Arrow a => Int -> a Int Int'? Полиморфизм означает, что всегда будет какая-то двусмысленность. – Carl