简体   繁体   中英

Check type of parameter in haskell

I have a function (a->a) which can take in different types but is there a way to determine what datatype the parameter is? Like

foo :: a -> a
foo a == int =..
foo a == char =..

Is there anyway to do a check like this in haskell?

No.

Use a datatype instead:

data MyType = MyInt Int | MyChar Char

foo :: MyType -> MyType
foo (MyInt i) = MyInt (i + 1) -- Or whatever
foo (MyChar c) = case c of {'a' -> MyChar 'A'; k -> MyChar k}

Though this of course restricts what types you can use.

Alternatively, use a typeclass:

class MyClass a where
    foo :: a -> a

instance MyClass Int where
    foo i = i + 1

instance MyClass Char where
    foo c = case c of {'a' -> 'A'; k -> k}

-- N.B. foo :: MyClass a => a -> a

Though once again this restricts what types you can use.

A way to do this, which however I do not recommend, is to add a Typeable constraint.

foo :: forall a . Typeable a => a -> a
foo x = case eqT :: a :~: Int of -- check if a = Int
   Just Refl -> x + 1            -- here we can use x as an Int
   Nothing   -> x                -- here we can not use x as an Int

For this to work you need a number of extensions, such as ScopedTypeVariables and GADTs .

This is usually not a good idea, in general. Before adopting this, you should first understand if you really need it: Typeable is very powerful and it should be used as a last resort, when simpler alternatives are not enough. Perhaps a custom type class could be a better solution for your tasks, as AJFarmar showed.

Also note that, without a type class constraint, a function foo :: a -> a , according to its "free theorem" (AKA parametricity property) can only be the identity function, or be undefined (eg infinite recursion, or a runtime exception).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM