Haskell:了解自定义数据类型

时间:2019-07-07 13:21:24

标签: haskell functional-programming pattern-matching algebraic-data-types custom-data-type

我正在尝试在Haskell中创建自己的自定义数据类型。

我具有以下数据类型:

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) 

但是,如果我有一个Length数据类型的实例,我希望能够提取RotationColourSpecial值。

如果我有:

L length

这里的lengthSpecial类型还是Length类型?如果length的类型为Special,是否有任何方法可以将其提取为Length的类型?

例如,以下代码有效吗?

takeL (x:xs)
      | x == (L length) = length

任何见解都会受到赞赏。

2 个答案:

答案 0 :(得分:4)

要使表达式L length有效,length必须是Length(因为L :: Length -> Special)。

takeL (x:xs)
      | x == (L length) = length

无效。除非您在某处重新定义了length,否则length是标准库中的函数[a] -> Int,因此L length是类型错误。

我认为您要在此处进行的只是模式匹配:

takeL (L length : xs) = length

答案 1 :(得分:3)

数据类型定义

data Special  = 

读取:Special是新的类型,以便创建类型为Special value

                  L Length 
  • 调用L l,其中l是类型Length的值;或

                | R Rotation 
    
  • 调用R r,其中r是类型Rotation的值;或

                | Col Colour  
    
  • 调用Col c,其中c是类型Colour的值。


要分析类型Special的值,需要考虑以下三种情况:

foo :: Special -> ...
foo val = 
    case val of
        L   l -> ...  
    l实际上是Length的情况下,
  • val是类型L l的值;或

        R   r -> ... 
    
  • r实际上是Rotation的情况下,
  • val是类型R r的值;或

        Col c -> ...  
    
  • c实际上是Colour的情况下,
  • val是类型Col c的值。

函数定义中的case语法也可以使用基于模式的子句来表达:

foo :: Special -> ...
foo (L   l) = ...
foo (R   r) = ...
foo (Col c) = ...