繁体   English   中英

检查haskell中的参数类型

[英]Check type of parameter in haskell

我有一个函数(a->a) ,可以接受不同的类型,但是有没有办法确定参数是什么数据类型? 喜欢

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

无论如何,在haskell中是否可以进行这样的检查?

没有。

请改用数据类型:

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}

尽管这当然限制了您可以使用的类型。

或者,使用类型类:

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

尽管这再次限制了您可以使用的类型。

实现此目的的一种方法(但是我建议这样做)是添加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

为此,您需要一些扩展,例如ScopedTypeVariablesGADTs

通常,这通常不是一个好主意。 在采用此方法之前,您首先应该了解您是否真正需要它: Typeable功能非常强大,当更简单的替代方法不够用时,应将其用作最后的手段。 就像AJFarmar展示的那样,自定义类型类可能是您任务的更好解决方案。

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

暂无
暂无

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

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