- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道newtype
更多时候与 data
进行比较在 Haskell 中,但我更多地是从设计角度而不是技术问题来进行这种比较。
在命令式/面向对象语言中,存在反模式“primitive obsession”,其中大量使用原始类型会降低程序的类型安全性,并意外地引入相同类型值的可互换性,否则本应用于不同的值目的。例如,很多东西都可以是字符串,但如果编译器能够静态地知道哪些是名称,哪些是地址中的城市,那就太好了。
那么,Haskell 程序员多久雇佣一次 newtype
为其他原始值提供类型区别?使用type
引入别名并为程序的可读性提供更清晰的语义,但不能防止意外的值交换。当我学习 Haskell 时,我注意到该类型系统与我遇到的任何类型系统一样强大。因此,我认为这是一种自然且常见的做法,但我还没有看到太多或任何关于 newtype
的使用的讨论。从这个角度来看。
当然,很多程序员的做法不同,但这在 haskell 中常见吗?
最佳答案
新类型的主要用途是:
我现在正在开发一个应用程序,在其中广泛使用新类型。 Haskell 中的 newtypes 纯粹是编译时概念。例如。使用下面的解包器,unFilename (Filename "x")
编译为与“x”相同的代码。运行时命中率绝对为零。有 data
类型。这使得它成为实现上述目标的一个非常好的方法。
-- | A file name (not a file path).
newtype Filename = Filename { unFilename :: String }
deriving (Show,Eq)
我不想意外地将其视为文件路径。它不是文件路径。它是数据库中某个位置的概念文件的名称。
对于算法来说,引用正确的事物非常重要,新类型可以帮助解决这一问题。这对于安全性也非常重要,例如,考虑将文件上传到 Web 应用程序。我有以下类型:
-- | A sanitized (safe) filename.
newtype SanitizedFilename =
SanitizedFilename { unSafe :: String } deriving Show
-- | Unique, sanitized filename.
newtype UniqueFilename =
UniqueFilename { unUnique :: SanitizedFilename } deriving Show
-- | An uploaded file.
data File = File {
file_name :: String -- ^ Uploaded file.
,file_location :: UniqueFilename -- ^ Saved location.
,file_type :: String -- ^ File type.
} deriving (Show)
假设我有这个函数可以从已上传的文件中清除文件名:
-- | Sanitize a filename for saving to upload directory.
sanitizeFilename :: String -- ^ Arbitrary filename.
-> SanitizedFilename -- ^ Sanitized filename.
sanitizeFilename = SanitizedFilename . filter ok where
ok c = isDigit c || isLetter c || elem c "-_."
现在我生成一个唯一的文件名:
-- | Generate a unique filename.
uniqueFilename :: SanitizedFilename -- ^ Sanitized filename.
-> IO UniqueFilename -- ^ Unique filename.
从任意文件名生成唯一的文件名是危险的,应该首先对其进行清理。同样,唯一的文件名通过扩展名始终是安全的。如果我愿意,我现在可以将文件保存到磁盘并将该文件名放入我的数据库中。
但是必须多次包装/展开也可能很烦人。从长远来看,我认为这是值得的,特别是为了避免值(value)不匹配。 ViewPatterns 有一定帮助:
-- | Get the form fields for a form.
formFields :: ConferenceId -> Controller [Field]
formFields (unConferenceId -> cid) = getFields where
... code using cid ..
也许您会说在函数中展开它是一个问题 - 如果您错误地将 cid
传递给函数怎么办?不是问题,所有使用 session ID 的函数都将使用 ConferenceId 类型。出现的是一种在编译时强制执行的函数到函数级别的契约系统。很不错。所以是的,我尽可能经常使用它,尤其是在大型系统中。
关于就类型安全而言,Haskell 类型与 newtype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/991467/
这个问题在这里已经有了答案: Casting vs using the 'as' keyword in the CLR (18 个答案) 关闭 2 年前。 这两个转换之间究竟有什么区别? SomeC
如何将 newtype 转换为 Int,反之亦然? 我尝试过: newtype NT1 = NT1 Integer fromNT1toInt :: NT1 -> Int fromNT1toInt x
真实世界的haskell 说: we will hide the details of our parser type using a newtype declaration 我不明白我们如何使用新类
我想定义一种“理想”类型,它是一个列表,但有一些结构。数字前奏已经定义了 Ring 的实例对于列表,但他们没有使用我想要的加法和乘法的定义。所以我认为在这种情况下我应该说 newtype Ideal
我正在用 SAT 做一些事情,我想要同时有“and”和“or”子句。 type AndClause = [Literal] type OrClause = [Literal] 但是我在使用它们时遇到
给定以下新类型: newtype Bar a = Bar { biz::Int -> Int -> Int } 是否可以对 Int -> Int 参数进行模式匹配? 例如,假设我想在 Bar 上对 m
我正在尝试理解 newtype 并认为这会起作用: module NT where newtype X = X Double newtype Y = Y Double doit :: X -> Y -
考虑以下代码示例,它创建了一个新类型来表示客户模型: module Main where import Effect (Effect) import Effect.Console ( logShow
假设我有这个新类型: newtype SomeType a = SomeType { foo :: OtherType a } 我要确保a是可显示的(属于类型类 Show x )。 我如何确保? (这
我有一个类型 class IntegerAsType a where value :: a -> Integer data T5 instance IntegerAsType T5 where v
Learn You a Haskell讨论 newtype . 它的签名如何Pair b a意味着传入的参数必须是一个元组? ghci> newtype Pair b a = Pair { getPa
我有兴趣为我的 monad 转换器堆栈获得缩放功能,该功能定义如下: newtype Awesome a = Awesome (StateT AwesomeState (ExceptT B.ByteS
我创建了一个 newtype为 Maybe Int : Prelude> newtype MaybeTuple = MaybeTuple { getMaybe :: Maybe Int} Prelud
这有什么区别: INPUT_FORMAT_TYPE = NewType('INPUT_FORMAT_TYPE', Tuple[str, str, str]) 和这个 INPUT_FORMAT_TYP
我有一个 UndecidableInstances我无法弄清楚如何避免使用 newtype 的问题.这是我最初的: {-# LANGUAGE TypeFamilies, FlexibleContext
我有一个 Haskell 项目,它使用了几个 newtypes . 我想导出这些表格,因此我可以将它包含在我的文档(非黑线鳕)中,例如作为 Markdown 表。我对此并不熟悉,但通过阅读,我的计划是
通常情况下,我正在编写剥离新类型的唯一构造函数的函数,例如在以下函数中返回不是 Nothing 的第一个参数: process (Pick xs) = (\(First x) -> x) . mcon
我最近在学习 PureScript,并做了一个在屏幕上绘制立方体的小应用程序。一切顺利,我在 Main 模块的顶部定义了一些 newtype,如下所示: newtype Vec2 = Vec2
Rewrite rules可以帮助您优化程序。我想知道如果我将对象包裹在 newtype 中它们是否会起作用.众所周知,newtype不会带来性能损失,它是一个在运行时消失的编译时包装器。所以我想知道
Difference between `data` and `newtype` in Haskell还有其他几个问题解决了数据和新类型之间的一般差异。我的问题是一个非常具体的问题。如果 G是某种类型,
我是一名优秀的程序员,十分优秀!