Haskell类型

Cor*_*rei 2 haskell functional-programming

如何在Haskell中找到值的类型?

我想要这样的东西:

data Vegetable = 
  Und Under
 |Abv Above

is_vegetable ::a->Bool  
is_vegetable a = if (a is of type Vegetable) then True else False
Run Code Online (Sandbox Code Playgroud)

更新:

我想要一个数据结构来模拟上面的树.

我还想要一些函数(is_drink,is_vegetable,is_wine,is_above),以便我可以在列表中应用一些过滤器. 在此输入图像描述

dav*_*420 16

你没有.你依靠类型系统来确保值是一个蔬菜---如果值不是一个蔬菜,你的程序将无法编译,更不用说运行了.

is_vegetable :: Vegetable -> Bool
is_vegetable _ = True  -- so there is not much point to this function
Run Code Online (Sandbox Code Playgroud)

在看到您的评论时编辑:

data Foodstuff = Vegetable Vegetable
               | Drink Drink

is_vegetable :: Foodstuff -> Bool
is_vegetable (Vegetable _) = True
is_vegetable _             = False
Run Code Online (Sandbox Code Playgroud)

但这可能仍然不是你想要的.相反,你可能想要类似的东西

    case myFood of
         Vegetable vegetable -> -- something involving `vegetable`
         Drink drink         -> -- something involving `drink`
Run Code Online (Sandbox Code Playgroud)


Mar*_*ler 9

你不能在Haskell做到这一点.所有函数参数都具有具体类型(如IntString),或者它们是类型变量(如a示例中所示).类型变量可以限制为属于某个类型类.

当您使用不受限制的类型变量时,您无法对该类型的值执行任何有趣的操作.通过将类型变量限制为类型类,您可以获得更多权力:如果有Num a,那么您知道这a是一种数字类型,因此您可以添加,多个等等.

从您的评论中,您可能需要一个(更大的)数据类型来保存树中不同类型的元素.这种Either a b类型可能派上用场.它要么是Left aRight b,所以你可以有一个像功能

is_vegetable :: Either Vegetable Drink -> Bool
is_vegetable (Left _) = True
is_vegetable (Right _) = False
Run Code Online (Sandbox Code Playgroud)

然后,您的树节点将成为Either Vegetable Dring元素.


Die*_*Epp 6

在Haskell中读取函数签名的提示:

f :: a -> Bool
Run Code Online (Sandbox Code Playgroud)

这意味着f接受一个可能是任何东西的参数,并且f没有关于该类型的任何信息.所以不可能f知道论证是否是一个Vegetable.只有三种可能的定义f(对于严格/非严格变体,还有两种可能的定义,为清楚起见,我省略了这两种定义):

-- version 1
f _ = True

-- version 2
f _ = False

-- version 3
f _ = undefined
Run Code Online (Sandbox Code Playgroud)

你看到的f是一个非常无聊的功能,因为它不允许对其参数有任何了解.你可以这样做:

isVegetable :: Typeable a => a -> Bool
isVegetable x = case cast x :: Maybe Vegetable of
                  Just _ -> True
                  Nothing -> False
Run Code Online (Sandbox Code Playgroud)

你需要创建一个Typeablefor 的实例Vegetable,

data Vegetable = ... deriving Typeable
Run Code Online (Sandbox Code Playgroud)

签名f :: Typeable a => a -> Bool意味着f具有一个参数,并且除了参数具有在运行时已知的类型之外,它不知道该参数.