我可以想到三种方法来将几何点定义为Haskell中的代数数据类型.我想将其定义为代数数据类型以获得更好的文档.
作为元组类型:
data Point a = Point a a
Run Code Online (Sandbox Code Playgroud)
作为一个元组:
data Point a= Point (a,a)
Run Code Online (Sandbox Code Playgroud)
作为记录:
data Point a = Point { pointx :: a, pointy :: a}
Run Code Online (Sandbox Code Playgroud)
哪个更好的设计/风格,为什么?
我认为这主要取决于您手头的用例.
虽然我从不使用数据Point = Point (a, a),因为这引入了一层间接,它使数据结构膨胀 - 由两个机器字 - 一个用于Point指针和指向其中元组的指针.
更好地使用type Point a = (a,a)它只是一个别名或newtype Point a = Point (a,a)在编译时得到优化,所以你在这种情况下有好处.
最灵活的(对于一些灵活的定义)是最后一种方法,尽管我会调用记录pr1并将pr2"投影到第一个/第二个组件".这种方法也非常适合使用镜头.
正如@nikitavolkov所说 - 出于性能原因,拥有严格的数据字段是一个好主意,但是因为我喜欢记录,所以我最终会选择
{-# LANGUAGE TemplateHaskell -#}
{-# LANGUAGE DeriveFoldable -#}
{-# LANGUAGE DeriveFunctor -#}
{-# LANGUAGE DeriveTraversable -#}
{-# LANGUAGE RecordWildCards #-}
import Control.Lens
data Point a = Point { _pr1 :: !a
, _pr2 :: !a
} deriving (..)
$(makeLenses ''Point)
Run Code Online (Sandbox Code Playgroud)
它可以让你使用的好处norm Point{..} = sqrt (_pr1^2 + _pr2^2)与RecordWildCards和镜头上的细微区别.
就在最近,我发现了严格的包,它提供了严格的数据集以及严格的IO操作.向我伸出的一件事是来自Data.Strict.Maybe的以下内容
请注意,严格的Maybe不是monad,因为
return ? >>= f = ?它不一定是相同的f ?.
我认为这也适用于严格的配对 - 因此在定义和/或使用严格的数据类型时请记住这一点.
| 归档时间: |
|
| 查看次数: |
344 次 |
| 最近记录: |