L01*_*man 3 haskell derived-types
我们不能做read someValue :: someDataType或show someValue为每种类型,因为deriving (Show, Read)必须在data声明中写.是否有一个案例,除了错误,我们不希望我们的类型可序列化?为什么Show与Read分开?是否有一个案例,除了错误,我们只想显示一些数据而不读它?如果没有,为什么不使用单一数据类型Serializable?
刚才,我正在使用Gloss库的Key数据类型,它是派生Show而不是Read,我不明白.这很遗憾,因为我想将控件的配置放在一个文件中,然后读取它,这样玩家就可以更改控件并拥有自己的配置.我不得不为Key,SpecialKey和MouseButton做包装,这不是什么大问题但是没用.
data Key' = Char' Char | SpecialKey' SpecialKey | MouseButton' MouseButton
deriving (Eq, Ord, Show, Read)
convertKey x = case x of
Char' c -> Char c
SpecialKey' sk -> SpecialKey sk
MouseButton' mb -> MouseButton mb
Run Code Online (Sandbox Code Playgroud)
aug*_*tss 11
首先,并非所有数据类型都可以显示,例如无法显示函数,因此并非所有数据类型都可以显示(也不能读取).最初的Haskell定义指定如果没有给出派生子句,那么将导出尽可能多的派生类.这使得很难知道实际派生了哪些类,因此更改了Haskell定义以强制显式派生子句.
其次,在原始的Haskell定义中show,read函数在Text类中捆绑在一起.当你得到这不是太大的问题Show及Read,但它是一种痛苦,当你手工编写它们.您经常要定义一个特殊的show函数,但现在您也被迫编写一个read函数,因此最好将它们分开.就个人而言,我几乎总是来自Show,但几乎从不Read.
在Show和Read班是不是真的意味着要用于序列化,而是进行简单的输入和输出.
Tho*_*son 10
为什么Show与Read分开
我不知道为什么这是最初的,但是觉得它应该持续存在,因为可以显示一些(很少)类型,或者显示占位符字符串,但是不能读回来.函数是典型的例子.
另一种思考方式:将事物放在单独的类中非常容易,但很难在一个类中处理太多的函数,这些函数在相同的上下文中并不总是有意义.许多人认为这个Num课程是这个问题的一个主要例子.
如何read键和其他类型不在Read
第一步:发送补丁添加Read到派生实例集.第二步:使用独立派生来解决问题:
{-# LANGUAGE StandaloneDeriving #-}
deriving instance Show Key
Run Code Online (Sandbox Code Playgroud)
第三步:使用CPP使您的代码可以使用任何版本的代码库,无论是具有Ben有朝一日会发布的Read实例的光泽库,还是没有版本的.
为什么不Serializable上课?
对于初学者,有一个Serialize类.此外,文本是序列化事物的可怕方式.也许你想要一个更加懒惰的序列化类,在这种情况下你应该看到Binary类.如果你担心性能,那么你可能会喜欢blaze-builder,尽管我老实说从未使用它.
并非每种类型都可序列化.你如何在String -> String和之间建立同构String?如果你给我Read和Show实例String -> String,我可以找到一个不可序列化的函数:
evil :: String -> String
evil s = map succ (read s s ++ " evil")
Run Code Online (Sandbox Code Playgroud)
假设
read (show evil) = evil
Run Code Online (Sandbox Code Playgroud)
我们得到了
evil (show evil)
= map succ (read (show evil) (show evil) ++ " evil")
= map succ (evil (show evil) ++ " evil")
= map succ (evil (show evil)) ++ "!fwjm"
Run Code Online (Sandbox Code Playgroud)
所以如果evil (show evil)定义了,那么它有第一个c满足的字符c = succ c,这是不可能的.
通常,函数无法序列化.有时,我们编写打包函数的数据类型,因此并非每个数据类型都可序列化.例如,
data Psychiatrist
= Listen (String -> Psychiatrist)
| Charge Int
Run Code Online (Sandbox Code Playgroud)
有时,即使对于这些类型,您也可以选择提供部分实现Read(有些情况下缺失)和Show(例如,使用占位符或函数列表),但没有规范的方法来选择它们或理由为什么你会期望两者.
正如其他人所提到的那样,严肃的序列化是其中的保留Serialize.我倾向于使用Show和Read用于诊断目的,特别是在ghci中尝试.为此目的,Show更有用,因为ghci有一个Haskell解析器来进行读取.
| 归档时间: |
|
| 查看次数: |
1522 次 |
| 最近记录: |