【问题标题】:Haskell conversion between typesHaskell 类型之间的转换
【发布时间】:2019-05-01 12:14:19
【问题描述】:

再次停留在一些可能是理论上的东西上。 Haskell 中有很多库,我想尽量少用。如果我有这样的类型:

data Note = Note { _noteID :: Int
                 , _noteTitle :: String
                 , _noteBody :: String
                 , _noteSubmit :: String
                 } deriving Show

并使用它来创建[Note {noteID=1...}, Note {noteID=2...}, ] 等列表。我现在有一个Note 类型的列表。现在我想使用writeFile 将其写入文件。考虑到 writeFile 的类型为FilePath -> String -> IO (),可能 ghc 不会允许它。但我也想避免一直解构(writeFile)和构造(readFile)类型,假设我不会离开Haskell“领域”。有没有办法做到这一点,而不使用特殊的库?再次:非常感谢。 Haskell 上的书籍很好,但 StackOverflow 是书籍和现实世界之间的粘合剂。

【问题讨论】:

  • 你有一个[Note]类型的列表。
  • 为什么不只是writeFile path show [Note {noteID=1...}, Note {noteID=2...}, ]
  • 这个问题非常广泛。您应该从“生成的文件应该是什么样子?”这个问题开始,然后编写代码来完成它。
  • 所以你想要一个FilePath -> [Note] -> IO ()类型的操作,但你有FilePath -> String -> IO (),你有一个[Note]类型的值?似乎您需要将该值转换为String 类型值,从而使用[Note] -> String 类型的函数。 show 就是这样一种功能。
  • 因此为您的数据类型派生Readread data :: [Note] 应该可以正常工作。嵌套引号应该不是问题,除非您需要 read 以外的其他内容来处理它,在这种情况下,我们将返回“生成的文件应该是什么样子?”

标签: haskell types type-conversion


【解决方案1】:

如果您正在寻找“快速修复”、一次性脚本或类似的东西,除了Show,您还可以派生Read,然后您就可以使用@987654323 @ 转换为Stringread 转换回来,例如:

data D = D { x :: Int, y :: Bool }
    deriving (Show, Read)

d1 = D 42 True

s = show d1
-- s == "D {x = 42, y = True}"

d2 :: D
d2 = read s
-- d2 == d1

但是,不要把它放在生产代码中。 首先,您隐含地依赖于记录的编码方式,并且没有任何检查可以防止细微的变化。 其次,read函数是partial——也就是说,如果它不能解析输入就会崩溃。 最后,如果您以这种方式保存数据,您将被这种记录格式卡住并且永远无法更改。

对于生产质量的解决方案,很抱歉,但您必须提出明确的、记录在案的序列化格式。没有办法 - 用任何语言。

【讨论】:

  • Fyodor,我想假设我正在尝试的一切,我希望能够在生产文件中使用。 Will Ness 和@assembly.jc 还提到了“显示”,这是在文件中获取内容的完美解决方案,但我认为需要“读取”才能将其取出。另一个缺点是在文件中再次嵌套引号,如果需要解析文件,我通常不喜欢这样做。
  • 如果这最终用于生产用途,那么您绝对不应该使用任何快速修复。想出一个格式,记录它,编写函数来转换,然后使用它们。相信我,长期的快速修复会回来咬你。
  • 请注意,readEither(我在 cmets 中提到过)仅解决了此处列出的第二个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 2010-12-29
  • 2011-08-18
  • 2012-11-02
  • 1970-01-01
相关资源
最近更新 更多