6

真实世界的haskell 说:

我们将使用 newtype 声明隐藏解析器类型的详细信息

我不明白我们如何使用新类型隐藏任何东西。谁能详细说明?我们试图隐藏什么以及我们如何做到这一点。

data ParseState = ParseState {
  string :: L.ByteString
, offset :: Int64           -- imported from Data.Int
} deriving (Show)


newtype Parse a = Parse {
    runParse :: ParseState -> Either String (a, ParseState)
}
4

2 回答 2

12

这个想法是结合模块 + 新类型,以防止人们看到我们如何实现事物的内部结构。

-- module A
module A (A, toA) where -- Notice we limit our exports
newtype A = A {unA :: Int}

toA :: Int -> A
toA = -- Do clever validation

-- module B
import A
foo :: A
foo = toA 1 -- Must use toA and can't see internals of A

这样可以防止模式匹配和任意构造A. 这让我们的A模块做出一定的假设,并不受惩罚A地改变内部结构!A

这特别好,因为在运行时newtypes 被删除了,所以做这样的事情几乎没有开销

于 2013-11-09T04:06:57.863 回答
6

您通过不导出内容来隐藏详细信息。所以有两个比较。一个是出口与不出口:

-- hidden: nothing you can do with "Parse a" values -- though
-- you can name their type
module Foo (Parse) where
newtype Parse a = Parse { superSecret :: a }

-- not hidden: outsiders can observe that a "Parse a" contains
-- exactly an "a", so they can do anything with a "Parse a" that
-- they can do with an "a"
module Foo (Parse(..)) where
newtype Parse a = Parse { superSecret :: a }

另一个更微妙,是 RWH 可能试图强调的一个,那就是typevs. newtype

-- hidden, as before
module Foo (Parse) where
newtype Parse a = Parse { superSecret :: a }

-- not hidden: it is readily observable that "Parse a" is identical
-- to "a", and moreover it can't be fixed because there's nothing
-- to hide
module Foo (Parse) where
type Parse a = a
于 2013-11-09T04:06:30.720 回答