使用带有代数数据类型的nullary构造函数而不是使用Maybe包装?

时间:2013-04-17 07:49:45

标签: haskell

我在我的代码中做了这种事情:

data MyType = Cons1 a b
data OtherType = OtherType
             { val1 :: Int
             , val2 :: String
             , val3 :: Maybe MyType
             }

我想知道将代码更改为更简洁/更简单以及优缺点是什么:

data MyType = Cons1 a b | Missing
data OtherType = OtherType
             { val1 :: Int
             , val2 :: String
             , val3 :: MyType
             }

我正在做的是将文件中的行读入[OtherType],每行有4列,第3列和第4列用于创建val3 :: MyType。目前我正在使用readMaybe来读取a和b,然后将它们传递给一个函数,如果它们中的任何一个是Nothing,则返回Nothing,如果它们是Just a和Just b则返回Just。我以为我可以改变它来返回Missing,从而删除一层包装。

2 个答案:

答案 0 :(得分:22)

如果所有Missing值都有可能MyType,则只应将MyType构造函数添加到Missing。您必须在处理Missing值的所有函数中处理MyType。如果其中大部分都是非全抛出错误或以其他方式失败 - 那么显然Missing不属于MyType,您应该只使用Maybe MyType

简单地说:如果选项是类型中固有的,则在类型中对其进行编码。否则,请将其分开。

答案 1 :(得分:10)

第二种方法有两个小优点:

  1. 通过削减间接级别,您编写的函数和遍历OtherType的值的函数通常会变得更简单(但不是很精彩)。
  2. 通过为您添加的Nullary构造函数选择一个好名称,您的代码可能会变得更加不言自明(与在不同位置使用相当通用的名称Nothing相比)。
  3. 一个很大的缺点是你失去了使用标准库为你提供Maybe - 所有预定义函数的能力 - 你必须自己编写相应的功能。