检查特定的数据构造函数

时间:2011-05-22 15:35:12

标签: haskell types typechecking

假设我定义了自己的数据类型,如

data MyData = A arg| B arg2| C arg3

我如何编写一个函数(例如:isMyDataType)来检查给定的参数是MyData中特定类型中的一个,并连续返回一个布尔值(True或False),例如:输入Ghci: isMyDataType B返回True,isMyDataType Int返回False。

3 个答案:

答案 0 :(得分:19)

我相信您希望功能测试特定的构造函数

isA :: MyData -> Bool
isB :: MyData -> Bool

如果是这样,那么你可以自己编写或者派生它们。实现看起来像:

isA (A _) = True
isA _     = False

isB (B _) = True
isB _     = False

要自动导出它们,只需使用derive库并在源代码中添加:

{-# LANGUAGE TemplateHaskell #-}
import Data.DeriveTH

data MyData = ...
    deriving (Eq, Ord, Show}

derive makeIs ''MyData
-- Older GHCs require more syntax: $( derive makeIs ''MyData)

另请注意:您的数据声明无效,名称必须大写,MyData而不是myData

最后,整个答案基于您想要测试构造函数的假设,而不是您所说的数据类型(在编译时进行静态检查,如Tarrasch所说)。

答案 1 :(得分:1)

Haskell总是检查类型是否有意义。如果您编写isMyDataType 4,编译器会立即投诉,因为4不是MyData类型,而是Int类型。

我不确定这是你要求的,但无论哪种方式,我强烈建议你尝试一下你在实践中提出的问题,这样你就可以亲自看看。最重要的是你在haskell中查看类型签名,这是学习haskell的关键。

答案 2 :(得分:0)

您可以使用Maybe s。您可以创建一组检查每种类型的功能

getA, getB, getC :: MyData a -> Maybe a
getA x = case x of {(A v) -> Just v; _ -> Nothing}
getB x = case x of {(B v) -> Just v; _ -> Nothing}
getC x = case x of {(C v) -> Just v; _ -> Nothing}

这为某些任务提供了一些实用的成语:

allAs :: [MyData a] -> [a]
allAs xs = mapMaybe getA xs

printIfA :: Show a => MyData a -> IO ()
printIfA x = maybe (return ()) print $ getA x