Just an idea; you can tell the number of parameters of a function at value level with the following code.
https://gist.github.com/nushio3/5867066
import Data.Typeable
import Test.Hspec
arityOf :: Typeable a => a -> Int
arityOf x = go $ typeOf x
where
go tr
| isFun $ typeRepTyCon tr = 1 + go (last $ snd $ splitTyConApp tr)
| otherwise = 0
funTyCon = typeRepTyCon $ typeOf ((1+):: Int -> Int)
isFun = (funTyCon ==)
main :: IO ()
main = hspec spec
func :: (Int -> Int) -> Int -> Int
func = undefined
spec :: Spec
spec = describe "arityOf" $ do
it "evaluates Integers correctly" $ arityOf (1::Int) `shouldBe` 0
it "evaluates Strings correctly" $ arityOf "(1::Int)" `shouldBe` 0
it "evaluates monads correctly" $ arityOf main `shouldBe` 0
it "evaluates multiplications correctly" $ arityOf ((*) :: Int -> Int -> Int)
`shouldBe` 2
it "is not deceived by non-tail argument" $ arityOf func `shouldBe` 2