简体   繁体   English

检查haskell中的参数类型

[英]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? 我有一个函数(a->a) ,可以接受不同的类型,但是有没有办法确定参数是什么数据类型? Like 喜欢

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

Is there anyway to do a check like this in haskell? 无论如何,在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. 实现此目的的一种方法(但是我建议这样做)是添加Typeable约束。

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 . 为此,您需要一些扩展,例如ScopedTypeVariablesGADTs

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. 在采用此方法之前,您首先应该了解您是否真正需要它: Typeable功能非常强大,当更简单的替代方法不够用时,应将其用作最后的手段。 Perhaps a custom type class could be a better solution for your tasks, as AJFarmar showed. 就像AJFarmar展示的那样,自定义类型类可能是您任务的更好解决方案。

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). 还要注意,没有类型类约束,根据其“自由定理”(AKA参数属性),函数foo :: a -> a只能是标识函数,也可以是未定义的(例如,无限递归或运行时)例外)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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