Haskell 中具有多个参数的新类型

Pis*_*tor 2 console haskell types functional-programming ghci

newtypes在 Haskell 中,我尝试调用我已声明的以下两个。

为什么这有效:

newtype CharList = CharList { get2CharList :: [Char] } deriving (Eq, Show)   

ghci> CharList "some"    
CharList {get2CharList = "some"}
Run Code Online (Sandbox Code Playgroud)

当这不起作用时:

newtype Pair a b = Pair { createPair :: (a, b) } deriving (Eq, Show)

ghci> Pair 2 4
<interactive>:13:1: error:
    * Couldn't match expected type: t0 -> t
                  with actual type: Pair a0 b0
    * The function `Pair' is applied to two value arguments,
        but its type `(a0, b0) -> Pair a0 b0' has only one
      In the expression: Pair 2 4
      In an equation for `it': it = Pair 2 4
    * Relevant bindings include it :: t (bound at <interactive>:13:1)
Run Code Online (Sandbox Code Playgroud)

它是否需要 Monad 才能工作,如下所示:Writer monad 及其类型声明 然后我是否必须在调用时约束类型newtype

newtype此外,如果我想要 a接受更多参数(例如 3),我该怎么办?

Mar*_*ann 5

newtypePair被声明为包含(或包装)值的元组,因此您必须提供它来创建值:

ghci> Pair (2, 4)
Pair {createPair = (2,4)}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令从Pair值中提取元组createPair

ghci> createPair $ Pair (2, 4)
(2,4)
Run Code Online (Sandbox Code Playgroud)

虽然类型给出为Pair a b(不带括号或逗号),但数据构造函数需要一个元组。类型声明在等号左边,数据构造函数在等号右边。

该语法Pair (2, 4)只是完整数据构造函数的简写,这也是可能的:

ghci> Pair { createPair = (2, 4) }
Pair {createPair = (2,4)}
Run Code Online (Sandbox Code Playgroud)

您可以用相同的方式创建具有更多类型参数的包装器:

newtype Triple a b c = T { getTriple :: (a, b, c) } deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

此示例还展示了一些可能有助于理解上述内容的内容。类型的名称不必与数据构造函数的名称相同。这里,类型的名称是Triple,而数据构造函数的名称是T

Triple您使用数据构造函数创建一个值T

ghci> T (1, "foo", True)
T {getTriple = (1,"foo",True)}
Run Code Online (Sandbox Code Playgroud)

该表达式的类型是:

ghci> :t T (1, "foo", True)
T (1, "foo", True) :: Num a => Triple a String Bool
Run Code Online (Sandbox Code Playgroud)