[英]Haskell type of
How can I find the type of a value in Haskell? 如何在Haskell中找到值的类型?
I want something like this: 我想要这样的东西:
data Vegetable =
Und Under
|Abv Above
is_vegetable ::a->Bool
is_vegetable a = if (a is of type Vegetable) then True else False
Update: 更新:
I want a datastructure to model the above tree. 我想要一个数据结构来模拟上面的树。
I would also like to have some functions (is_drink, is_vegetable,is_wine,is_above) so that I can apply some filters on a list. 我还想要一些函数(is_drink,is_vegetable,is_wine,is_above),以便我可以在列表中应用一些过滤器。
You don't. 你没有。 You rely on the type system to ensure that the value is a Vegetable --- if the value is not a Vegetable, your program won't compile, much less run.
你依靠类型系统来确保值是一个蔬菜---如果值不是一个蔬菜,你的程序将无法编译,更不用说运行了。
is_vegetable :: Vegetable -> Bool
is_vegetable _ = True -- so there is not much point to this function
Edit, upon seeing your comment: 在看到您的评论时编辑:
data Foodstuff = Vegetable Vegetable
| Drink Drink
is_vegetable :: Foodstuff -> Bool
is_vegetable (Vegetable _) = True
is_vegetable _ = False
But this is still probably not what you want. 但这可能仍然不是你想要的。 Instead you probably want something like
相反,你可能想要类似的东西
case myFood of
Vegetable vegetable -> -- something involving `vegetable`
Drink drink -> -- something involving `drink`
You cannot do this in Haskell. 你不能在Haskell做到这一点。 All function arguments have concrete types (like
Int
and String
) or they are type variables (like the a
in your example). 所有函数参数都有具体的类型(如
Int
和String
),或者它们是类型变量 (如示例中的a
)。 Type variables can be restricted to belong to a certain type class . 类型变量可以限制为属于某个类型类 。
When you use an unrestricted type variable, then you cannot do anything interesting with the values of that type. 当您使用不受限制的类型变量时,您无法对该类型的值执行任何有趣的操作。 By restricting the type variable to a type class, you get more power: if you have
Num a
, then you know that a
is a numeric type and so you can add, multiple, etc. 通过将类型变量限制为类型类,您可以获得更多权力:如果您有
Num a
,那么您知道a
是数字类型,因此您可以添加,多个等。
From your comment, it sounds like you need a (bigger) data type to hold the different types of elements in your tree. 从您的评论中,您可能需要一个(更大的)数据类型来保存树中不同类型的元素。 The
Either ab
type may come in handy here. 这
Either ab
型都可以派上用场。 It is either Left a
or Right b
and so you can have a function like 它是
Left a
或Right b
,因此你可以拥有类似的功能
is_vegetable :: Either Vegetable Drink -> Bool
is_vegetable (Left _) = True
is_vegetable (Right _) = False
Your tree nodes will then be Either Vegetable Dring
elements. 然后,您的树节点将成为
Either Vegetable Dring
元素。
Tip for reading function signatures in Haskell: 在Haskell中读取函数签名的提示:
f :: a -> Bool
This means f
takes one argument which could be anything , and f
does not have any information about the type. 这意味着
f
接受一个可能是任何东西的参数,并且f
没有关于该类型的任何信息。 So it is impossible for f
to know if the argument is a Vegetable
. 所以
f
不可能知道论证是否是一个Vegetable
。 There are only three possible definitions for f
(two more for strict / non-strict variants, which I'm omitting for clarity): f
只有三种可能的定义(对于严格/非严格变体,有两种可能的定义,为清楚起见我省略了这两种定义):
-- version 1
f _ = True
-- version 2
f _ = False
-- version 3
f _ = undefined
You see f
is a very boring function because it is not allowed to know anything about its parameter. 你看
f
是一个非常无聊的函数,因为它不允许知道它的参数。 You could do something like this: 你可以这样做:
isVegetable :: Typeable a => a -> Bool
isVegetable x = case cast x :: Maybe Vegetable of
Just _ -> True
Nothing -> False
You would need to create an instance of Typeable
for Vegetable
, 你需要创建一个
Typeable
for Vegetable
的实例,
data Vegetable = ... deriving Typeable
The signature f :: Typeable a => a -> Bool
means that f
has one parameter, and it does not know anything about that parameter except that the parameter has a type that is known at runtime. 签名
f :: Typeable a => a -> Bool
意味着f
有一个参数,并且除了参数具有在运行时已知的类型之外,它不知道该参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.