我具有以下自定义数据类型:
type Length = Integer
type Rotation = Integer
data Colour = Colour { red, green, blue, alpha :: Int }
deriving (Show, Eq)
data Special
= L Length
| R Rotation
| Col Colour
deriving (Show, Eq)
说我有以下形式的元组:
let x = ("Jump", R 90)
然后我使用以下命令在元组中提取第二个值:
snd x = R 90
有什么方法可以使用模式匹配从R 90中获取Rotation值90,以便可以在其他代码区域中使用它?当我使用snd x
时,结果的类型为Special类型,但是我只想获取Rotation值。任何见解都会受到赞赏。
答案 0 :(得分:5)
R
是Special
数据类型的构造函数。为了从Rotation
中提取R
,您需要编写以下函数:
unsafeExtractRotation :: Special -> Rotation
unsafeExtractRotation (R rotation) = rotation
但是,此函数是 unsafe (顾名思义),因为它是部分函数:不能处理所有情况。根据函数类型,它应该与Special
数据类型的任何值一起使用,因此可以将L
构造函数传递给此函数,它将崩溃,后来可能非常崩溃。找出此类错误的来源很困难。
更安全的功能如下所示:
extractRotation :: Special -> Maybe Rotation
extractRotation (R rotation) = Just rotation
extractRotation _ = Nothing
它不会崩溃。相反,它会强制您明确处理通过其他构造函数的情况。
答案 1 :(得分:1)
根据您提供的信息,我可以提出三个想法,一个来自Shersh,但您可以使用一个更适合您的代码的想法:
-- If is not of Rotation type, value is 0
specialToRotation (R n) = n
specialToRotation _ = 0
-- If not of Rotation type, pattern matching failure
specialToRotation2 (R n) = n
-- If not of Rotation type, value is Nothing
specialToRotation3 (R n) = Just n
specialToRotation3 _ = Nothing
选项2)并非完全错误,Haskell中有很多功能是局部的,请从列表api的head
和tail
中考虑。两者都没有空列表的定义。所以也许您可以使用它。