假设我定义了自己的数据类型,如
data MyData = A arg| B arg2| C arg3
我如何编写一个函数(例如:isMyDataType
)来检查给定的参数是MyData
中特定类型中的一个,并连续返回一个布尔值(True或False),例如:输入Ghci:
isMyDataType B
返回True,isMyDataType Int
返回False。
答案 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