7
votes

I want to have a function that determines if a type is a function type, like this:

isFunction : Type -> Bool
isFunction (a -> b) = True
isFunction _ = False

This returns True for all inputs, however. How can I make this work?

2
Here is how you can do this in Haskell. Maybe it's possible to adapt this for Idris, since it has typeclasses (however I don't know, how expressive they are). Do you need isFunction for arity-generic programming? The standard way to write an arity-generic function is to pass the arity explicitly, so you can compute a signature from it. You can read more here.user3237465
@user3237465: Ideally I want to be able to write isFunction String or isFunction (String -> String) rather than isFunction "" or isFunction (++)Adrian

2 Answers

8
votes

Matching on a Type is known as type-casing. Being able to do this would break a concept called parametricity which is very valuable.

https://stackoverflow.com/a/23224110/108359

Idris does not support type-casing. I think it may have tried at one stage, but people gave up on that quickly. It also used to give errors when type-casing was attempted but the check caused bugs and so has been disabled for now.

While you don't get errors any more, you can't provide an implementation of Type -> Bool which will work differently to const True or const False.

So sorry, this function is not possible. It might sound like a limitation but every time I thought I had a motivation for a function similar to this, I eventually figured out that I could have structured my program in a more explicit way instead.

1
votes

The question here would be: Why do you need something like this?

Do you need to find out if any arbitrary Idris type is a function or not? Or do you just need to find this out from a specific subset of Idris types? I can't figure out possible applications for the 1st one, but if it's the 2nd one you need, then you could define your own embedded language for dealing with values with these types, like this:

data Ty = TyNat | TyString | TyFun Ty Ty | ...

isFunction : Ty -> Bool
isFunction (TyFun _ _) = True
isFunction _ = False

Check out this talk for more information about how to implement these kind of embedded languages: https://vimeo.com/61663317