【发布时间】:2015-11-19 20:47:18
【问题描述】:
假设我有以下 Haskell 代码:
data Option
= Help
| Opt1 Int Double String
-- more options would be here in a real case
handleOption :: Option -> IO ()
handleOption option = case option of
Help -> handleHelp
Opt1 n f s -> handleOpt1 n f s
handleHelp :: IO ()
handleHelp = print "help"
handleOpt1 :: Int -> Double -> String -> IO ()
handleOpt1 n f s = print (n, f, s)
在上面的代码中,提前解构对象在我看来是一种浪费,因为我可以将数据整齐地捆绑在一起。现在我必须单独传递 Opt1 的每个部分,或者创建一个单独的数据类型来将它们拖走。是否可以将整个Opt1 传递给handleOpt1 而不允许传入一般的Option 实例,例如使handleOpt1 Help 编译错误?
下面的示例伪代码:
data Option
= Help
| Opt1 Int Double String
handleOption :: Option -> IO ()
handleOption option = case option of
Help -> handleHelp
opt1 @ Opt1{} -> handleOpt1 opt1
handleHelp :: IO ()
handleHelp = print "help"
handleOpt1 :: Option:Opt1 -> IO ()
handleOpt1 (Opt1 n f s) = print (n, f, s)
【问题讨论】:
-
编译器只能检查类型是否正确。它无法检查传递给
handleOpt1的值是否是使用正确的构造函数构造的(通常;它原则上可以检查源代码中显式传递的值是否正确,但由于通常传递的值是在运行时计算的,所以没有人编写代码来检查异常情况)。 -
你可以为选项创建一个类型类,找出某种方法来使用存在量化来组合它们(并从组合中提取有用的信息)......或者你可以只是不要再为琐碎的事情担心了。如果你的程序中有什么东西影响了你的表现,那可能不是。
-
“浪费”是指设计层面,而不是性能层面。更新了我的帖子。
标签: haskell types constructor