如果您在Haskell中编写生物信息学算法,您可能会使用代数数据类型来表示核苷酸:
data Nucleotide = A | T | C | G
你会在标准ML或OCaml中做同样的事情,我认为(我从未真正使用过)。
类型Nucleotide
的值可以清楚地包含在两位中。但是,这样做会导致访问时间比每个Nucleotide
值使用一个字节要慢,因为您需要使用二元运算符选择两个感兴趣的位。
data Maybe a = Just a | Nothing
显然,Maybe a
形式的Just a
值在逻辑上大于Nothing
形式的值。在这样一个极端的例子中:
data Hulk a b c d e = Big a b c d e | Little
您绝对不希望存储Little
值空指针或Big
值中包含的五个值的零值。我假设你只是使用堆分配的可变大小的内存,在开头有一个构造函数ID(例如0
为Big
而1
为{{1} }})。但是,如果要在堆栈上存储Little
值(更快的表示),则必须将空白内存与Hulk
值一起存储,以便{{1}类型的所有值都存储是相同的大小。另一个权衡。
Simon Marlow在previous StackOverflow question回答了关于GHC的一般性问题。但是,我有三个相关的问题仍然没有答案:
Little
的两位表示?这种记忆效率对于许多生物信息学应用是必要的;如果每个Hulk
必须是一个字节,那么高性能的生物信息学算法就不得不求助于手工操作。答案 0 :(得分:2)
没有一个答案:数据类型是抽象结构,可以由实施者自行决定以各种方式实现。在实践中,诸如单独编译之类的考虑往往会在某种程度上限制事物。
对于将仅包含nullary构造函数的数据类型打包到尽可能少的特定情况,您可以继续将函数从数据类型定义为小整数并返回。由抽象类型(或在Haskell中,newtype
)隐藏的整数类型也是一个合理的选择。将小整数打包并打包成您正在使用的任何聚合形式将是您的工作。
顺便说一句,Real World OCaml对OCaml值的表示有a very nice chapter(粗略总结:就此问题而言,与GHC没有太大差别)。