我对Haskell Show
和Read
的{{3}}的理解是read.show
应该是身份。如果为true,那么read
需要能够进行一些非常混乱的字符串解析,或者show
必须提供相当有限的功能(从用户体验的角度来看)。
是read.show == id
的情况,如果是这样的话,对于函数命名和调用,接受的Haskell实践是什么?对于更丰富的(字符串)值表示?
答案 0 :(得分:5)
首先,show
应该按照Haskell语法生成一个字符串 - 理想情况下,应该能够剪切&将其粘贴到Haskell文件中并使其工作。
话虽如此,预计read . show
将成为身份。但是,有时它会放松一点,只需要
read (show x) == x
其中(==)
是相关Eq
实例定义的等价。
我相信这个原型的例子是Data.Set.Set
,它在内部表示使用平衡二叉搜索树(BST)的集合。它的Show
实例生成
fromList [1,2,3,4,6,7]
read
返回这样一个字符串可能会产生一个不同的BST,但仍旧==
的旧BST。从用户的角度来看,没有(可观察到的)差异。
打印自定义“opaque”类型时,通常可以使用相同的fromSomeTransparentType value
字符串编码。
最后,我猜这些Show
相关的“社交合同”在库中比在应用程序中更受尊重。这是因为在应用程序中,有时可以合理地假设没有其他人 - 但应用程序本身 - 将使用这些实例。例如,我认为这对申请来说是可以的:
data Exp = Add Exp Exp | ...
instance Show Exp where
show (Add e1 e2) = "(" ++ show e1 ++ ", " ++ show e2 ++ ")"
一般而言,“其他”法律show . read == id
并不成立。首先,read
是部分的。其次,即使忽略偏倚,也允许read
方法对其输入更宽松,例如将重复的空格视为单个空格,或忽略多余的括号:(如AJFarmar在下面所述)
show (read "Just (((6)))") = "Just 6"