data
和 type
关键字总是让我感到困惑。
我想知道data
和type
之间有什么区别以及如何使用它们。
最佳答案
type
声明一个类型同义词。类型同义词是现有类型的新名称。例如,String
的定义方式是 in the standard library :
type String = [Char]
String
是 Char
列表的另一个名称。 GHC 将在编译时用 [Char]
替换程序中所有 String
的用法。
需要明确的是,String
字面意思是一个Char
列表。这只是一个别名。您可以对 String
值使用所有标准列表函数:
-- length :: [a] -> Int
ghci> length "haskell"
7
-- reverse :: [a] -> [a]
ghci> reverse "functional"
"lanoitcnuf"
<小时/>
data
声明一个新数据类型,与类型同义词不同,它与任何其他类型都不同。数据类型有许多构造函数来定义您的类型的可能情况。例如,Bool
的定义方式是 in the standard library :
data Bool = False | True
Bool
值可以是 True
或 False
。数据类型支持模式匹配,允许您对数据类型的值执行运行时案例分析。
yesno :: Bool -> String
yesno True = "yes"
yesno False = "no"
data
类型可以有多个构造函数(与 Bool
一样),可以由其他类型参数化,可以在其中包含其他类型,并且可以递归引用自身。这是一个异常(exception)模型,它演示了这一点; Error a
包含类型 a
的错误消息,以及可能导致该错误的错误。
data Error a = Error { value :: a, cause :: Maybe (Error a) }
type ErrorWithMessage = Error String
myError1, myError2 :: ErrorWithMessage
myError1 = Error "woops" Nothing
myError2 = Error "myError1 was thrown" (Just myError1)
重要的是要认识到 data
声明了一个与系统中任何其他类型不同的新类型。如果 String
已声明为 data
类型,包含 Char
列表(而不是类型同义词) ,您将无法在其上使用任何列表函数。
data String = MkString [Char]
myString = MkString ['h', 'e', 'l', 'l', 'o']
myReversedString = reverse myString -- type error
<小时/>
还有另一种类型声明:newtype
。这与 data
声明非常相似 - 它引入了与任何其他类型分开的新数据类型,并且可以进行模式匹配 - 除非您仅限于具有单个字段的单个构造函数。换句话说,newtype
是包装现有类型的data
类型。
重要的区别在于 newtype
的成本:编译器 promise newtype
的表示方式与其类型相同包裹。打包或解压 newtype
没有运行时成本。这使得 newtype 对于在值之间进行管理(而不是结构)区分非常有用。
newtype
与类型类交互良好。例如,考虑 Monoid
,它是一种类型类,具有组合元素 (mappend
) 和特殊“空”元素 (mempty
) 的方式。 Int
可以通过多种方式变成 Monoid
,包括与 0 相加和与 1 相乘。我们如何选择将哪一个用于可能的 Monoid
Int
的实例?最好不要表达偏好,并使用 newtype 来启用任一用途,而无需运行时成本。释义the standard library :
-- introduce a type Sum with a constructor Sum which wraps an Int, and an extractor getSum which gives you back the Int
newtype Sum = Sum { getSum :: Int }
instance Monoid Sum where
(Sum x) `mappend` (Sum y) = Sum (x + y)
mempty = Sum 0
newtype Product = Product { getProduct :: Int }
instance Monoid Product where
(Product x) `mappend` (Product y) = Product (x * y)
mempty = Product 1
关于haskell - "data"和 "type"关键字有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33316533/