[英]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
. 为此,您需要一些扩展,例如
ScopedTypeVariables
和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. 在采用此方法之前,您首先应该了解您是否真正需要它:
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.