- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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/
在 Haskell 中,类型声明使用双冒号,即 (::),如 not::Bool -> Bool。 但是在许多语法与 Haskell 类似的语言中,例如榆树、 Agda 、他们使用单个冒号(:)来声明
insertST :: StateDecoder -> SomeState -> Update SomeState SomeThing insertST stDecoder st = ... Stat
如果这个问题有点含糊,请提前道歉。这是一些周末白日梦的结果。 借助 Haskell 出色的类型系统,将数学(尤其是代数)结构表达为类型类是非常令人愉快的。我的意思是,看看 numeric-prelud
我有需要每 5 分钟执行一次的小程序。 目前,我有执行该任务的 shell 脚本,但我想通过 CLI 中的键为用户提供无需其他脚本即可运行它的能力。 实现这一目标的最佳方法是什么? 最佳答案 我想你会
RWH 面世已经有一段时间了(将近 3 年)。在在线跟踪这本书的渐进式写作之后,我渴望获得我的副本(我认为这是写书的最佳方式之一。)在所有相当学术性的论文中,作为一个 haskell 学生,读起来多么
一个经典的编程练习是用 Lisp/Scheme 编写一个 Lisp/Scheme 解释器。可以利用完整语言的力量来为该语言的子集生成解释器。 Haskell 有类似的练习吗?我想使用 Haskell
以下摘自' Learn You a Haskell ' 表示 f 在函数中用作“值的类型”。 这是什么意思?即“值的类型”是什么意思? Int 是“值的类型”,对吗?但是 Maybe 不是“值的类型”
现在我正在尝试创建一个基本函数,用于删除句子中的所有空格或逗号。 stringToIntList :: [Char] -> [Char] stringToIntList inpt = [ a | a
我是 Haskell 的新手,对模式匹配有疑问。这是代码的高度简化版本: data Value = MyBool Bool | MyInt Integer codeDuplicate1 :: Valu
如何解释这个表达式? :t (+) (+3) (*100) 自 和 具有相同的优先级并且是左结合的。我认为这与 ((+) (+3)) (*100) 相同.但是,我不知道它的作用。在 Learn
这怎么行 > (* 30) 4 120 但这不是 > * 30 40 error: parse error on input ‘*’ 最佳答案 (* 30) 是一个 section,它仍然将 * 视为
我想创建一个函数,删除满足第二个参数中给定谓词的第一个元素。像这样: removeFirst "abab" ( 'b') = "abab" removeFirst [1,2,3,4] even =
Context : def fib(n): if n aand returns a memoized version of the same function. The trick is t
我明白惰性求值是什么,它是如何工作的以及它有什么优势,但是你能解释一下 Haskell 中什么是严格求值吗?我似乎找不到太多关于它的信息,因为惰性评估是最著名的。 他们各自的优势是什么。什么时候真正使
digits :: Int -> [Int] digits n = reverse (x) where x | n digits 1234 = [3,1,2,4]
我在 F# 中有以下代码(来自一本书) open System.Collections.Generic type Table = abstract Item : 'T -> 'U with ge
我对 Haskell 比较陌生,过去几周一直在尝试学习它,但一直停留在过滤器和谓词上,我希望能得到帮助以帮助理解。 我遇到了一个问题,我有一个元组列表。每个元组包含一个 (songName, song
我是 haskell 的初学者,我试图为埃拉托色尼筛法定义一个简单的函数,但它说错误: • Couldn't match expected type ‘Bool -> Bool’
我是 Haskell 语言的新手,我在使用 read 函数时遇到了一些问题。准确地说,我的理解是: read "8.2" + 3.8 应该返回 12.0,因为我们希望返回与第二个成员相同的类型。我真正
当我尝试使用真实项目来驱动它来学习 Haskell 时,我遇到了以下定义。我不明白每个参数前面的感叹号是什么意思,我的书上好像也没有提到。 data MidiMessage = MidiMessage
我是一名优秀的程序员,十分优秀!