这是什么意思?

use*_*438 6 haskell cardano

我正在努力学习Haskell.

我在这里阅读代码[1].我只是复制并过去代码的一部分:46和298-300.

问题:(..)是什么意思?

我很难过,但我没有结果.

module Pos.Core.Types(
-- something here

 SharedSeed (..) -- what does this mean?

) where


newtype SharedSeed = SharedSeed
{ getSharedSeed :: ByteString
} deriving (Show, Eq, Ord, Generic, NFData, Typeable)
Run Code Online (Sandbox Code Playgroud)

[1] https://github.com/input-output-hk/cardano-sl/blob/master/core/Pos/Core/Types.hs

Bar*_*icz 5

它表示"导出此数据类型的所有构造函数和记录字段".

当编写一个模块的出口列表中,有三个4的方式,你可以导出的数据类型:

module ModuleD(
    D,       -- just the type, no constructors
    D(..),   -- the type and all its constructors
    D(DA)    -- the type and the specific constructor
    ) where

data D = DA A | DB B
Run Code Online (Sandbox Code Playgroud)

如果不导出任何构造函数,则无法构造类型,至少直接构造.如果您想要对数据类型强制执行某些运行时不变量,这将非常有用:

module Even (evenInt, toInt) where

newtype EvenInt = EvenInt Int deriving (Show, Eq)

evenInt :: Int -> Maybe EvenInt
evenInt x = if x `mod` 2 == 0 then Just x else Nothing

toInt :: EvenInt -> Int
toInt (EvenInt x) = x
Run Code Online (Sandbox Code Playgroud)

调用者代码现在可以使用此类型,但只能以允许的方式使用:

x = evenInt 2
putStrLn $ if isJust x then show . toInt . fromJust $ x else "Not even!"
Run Code Online (Sandbox Code Playgroud)

作为旁注,toInt为方便起见,通常通过记录语法间接实现:

data EvenInt = EvenInt { toInt :: Int }
Run Code Online (Sandbox Code Playgroud)

4@leftaroundabout的回答

  • _export此数据类型的所有构造函数_←不仅是构造函数,也是记录字段. (3认同)

lef*_*out 5

导入/导出列表的语法与Haskell本身的语法没有多大关系.它只是一个以逗号分隔的列表,列出了您要从模块中导出的所有内容.现在,那里存在一个问题,因为Haskell确实有两种语言,其符号可能具有相同的名称.这与newtype您的示例中的一样特别常见:您有一个类型级名称 SharedSeed :: *,还有一个值级名称(数据构造函数)SharedSeed :: ByteString -> SharedSeed.

这只发生在大写名称中,因为类型级别的小写始终是本地类型变量.因此,导出列表中的约定是大写名称引用类型.

但只是导出类型不允许用户实际构造该类型的值.这通常是谨慎的:并非所有的内部表示值都可能构成newtype的合法值(参见Bartek的例子),因此最好只导出一个安全的智能构造函数而不是不安全的数据构造函数.

但有时候,你确实希望使数据构造函数可用,当然对于多构造函数类型Maybe.为此,导出列表有三种语法可供您使用:

module Pos.Core.Types(
Run Code Online (Sandbox Code Playgroud)
  • SharedSeed (SharedSeed)将导出构造函数SharedSeed.在这种情况下,这当然是唯一的构造函数,但如果有其他构造函数,则不会使用此语法导出它们.

  • SharedSeed (..)将导出所有构造函数.同样,在这种情况下,这只是SharedSeed,但例如Maybe,它将导出两者NothingJust.

  • pattern SharedSeedShareSeed作为独立模式导出(独立于ShareSeed类型的导出).这需要-XPatternSynonyms扩展.

    )
    
    Run Code Online (Sandbox Code Playgroud)