简体   繁体   English

Haskell类型

[英]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). 所有函数参数都有具体的类型(如IntString ),或者它们是类型变量 (如示例中的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 aRight 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.

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