Haskell:理解自定义数据类型

Haskell:理解自定义数据类型,haskell,functional-programming,pattern-matching,algebraic-data-types,custom-data-type,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 Rotati

我试图在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) 
但是,如果我有一个
特殊
数据类型的实例,我希望能够提取
长度
旋转
颜色

如果我有:

L length
这里的
length
是属于
Special
类型还是属于
length
类型?如果
length
属于
Special
类型,是否有任何方法将其提取为
length
类型

例如,以下代码有效吗

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

非常感谢您的见解。

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

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

我想你要做的只是模式匹配:

takeL (L length : xs) = length

数据类型定义

data Special  = 
读取:
Special
是一种新类型,要创建
Special
类型的值

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

                | R Rotation 
    
                | Col Colour  
    
        R   r -> ... 
    
        Col c -> ...  
    
  • 调用
    rr
    ,其中
    R
    旋转类型的值;或

                | R Rotation 
    
                | Col Colour  
    
        R   r -> ... 
    
        Col c -> ...  
    
  • 调用
    Col c
    ,其中
    c
    color
    类型的值


要分析
特殊
类型的值,需要考虑三种情况:

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

                | R Rotation 
    
                | Col Colour  
    
        R   r -> ... 
    
        Col c -> ...  
    
  • r
    Rotation
    类型的值,如果
    val
    实际上是
    r
    ;或

                | R Rotation 
    
                | Col Colour  
    
        R   r -> ... 
    
        Col c -> ...  
    
  • c
    color
    类型的值,在
    val
    实际为
    Col c
    的情况下

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

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

“提取价值”是什么意思?这就是所谓的“总和类型”——因此它由这些类型之一的值组成,而不是它们的集合。具体地说,一个元素可能是
L1
R42
——它们都不能从中提取
颜色。您可能需要一个“产品类型”,即
data Special=Special Length Rotation color
——其中该类型的每个值都有
Length
Rotation
color
可以提取的值。您只需解压缩数据构造函数即可。@RobinZigmond我不希望数据类型是产品数据类型,因为我希望Special是长度、旋转或颜色中的一种。@ceno980-感谢您的澄清,在这种情况下,您的类型确实是正确的。但在这种情况下,不清楚“提取”是什么意思,因为每个值只能提取三个分量中的一个。如果要匹配它使用的构造函数之一,可以使用模式匹配或
case
表达式进行匹配。关于您最近的编辑,在表达式
L length
中,则
length
必须是
length
(即
整数
),这取决于您如何定义构造函数。