Haskell 程序:从一个构造函数调用另一个构造函数


在 Haskell 中,我们可以使用用户定义的函数从一个构造函数调用另一个构造函数。在第一个示例中,我们将使用 (newPerson name = Person name 10) 构造函数,在第二个示例中,我们将使用 (newPerson n a = Person { name = n, age = a }) 构造函数。在第三个示例中,我们将使用 (clonePerson p = p { name = name p ++ " clone" }) 构造函数,在第四个示例中,我们将使用 (clonePerson p = p { name = name p ++ " clone" }) 构造函数。

方法 1:使用用户定义的函数从一个构造函数调用另一个构造函数

在这种方法中,我们定义了一个数据类型 Person,它有两个字段,一个名称 (String) 和一个年龄 (Int)。然后,我们定义一个新的构造函数 newPerson,它接受一个名称并创建一个具有该年龄的新 Person 对象。我们还定义了一个 printPerson 函数,它接受一个 Person 对象并打印其名称和年龄。

算法

  • 步骤 1 − 定义数据类型 ‘Person’,它有两个字段:name 和 age。

  • 步骤 2 − 定义构造函数来创建一个新的 Person 对象,如下所示:

  • newPerson name = Person name 10.

  • 步骤 3 − 定义 printPerson 函数,如下所示:

  • printPerson (Person name age) = putStrLn $ name ++ " is " ++ show age ++ " years old".

  • 步骤 4 − 程序执行将从 main 函数开始。main() 函数控制整个程序。它被写成 main = do。

  • 步骤 5 − 定义名为 ‘p1’ 和 ‘p2’ 的变量,它们将调用 ‘Person’ 对象,并打印其详细信息。当一个构造函数调用另一个构造函数时,就会发生这种情况。

示例 1

在此示例中,一个构造函数通过使用用户定义的函数从另一个构造函数中被调用。

data Person = Person String Int

newPerson :: String -> Person
newPerson name = Person name 10

printPerson :: Person -> IO ()
printPerson (Person name age) = putStrLn $ name ++ " is " ++ show age ++ " years old"

main :: IO ()
main = do
  let p1 = Person "John" 30
      p2 = newPerson "Jane"
  printPerson p1
  printPerson p2

输出

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
John is 30 years old
Jane is 10 years old

示例 2

在此示例中,定义了一个具有两个字段 name 和 age 的 Person 数据类型。它还定义了两个函数 newPerson 和 clonePerson,分别用于创建具有给定名称和年龄的新 Person,以及创建给定 Person 的克隆,并在其名称后附加 " clone"。

data Person = Person { name :: String, age :: Int } deriving (Show)

newPerson :: String -> Int -> Person
newPerson n a = Person { name = n, age = a }

clonePerson :: Person -> Person
clonePerson (Person n a) = Person { name = n ++ " clone", age = a }

main :: IO ()
main = do
  let person1 = newPerson "Alice" 25
      person2 = clonePerson person1
  putStrLn $ "Person 1: " ++ show person1
  putStrLn $ "Person 2: " ++ show person2

输出

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
Person 1: Person {name = "Alice", age = 25}
Person 2: Person {name = "Alice clone", age = 25}

示例 3

在此示例中,我们使用记录语法定义了 clonePerson 函数,以根据给定的 Person 对象 p 创建一个新的 Person 对象。我们只需复制 age 字段并将字符串 " clone" 附加到 name 字段。

data Person = Person { name :: String, age :: Int } deriving (Show)

newPerson :: String -> Int -> Person
newPerson n a = Person { name = n, age = a }

clonePerson :: Person -> Person
clonePerson p = p { name = name p ++ " clone" }

main :: IO ()
main = do
  let person1 = newPerson "Alice" 25
      person2 = clonePerson person1
  putStrLn $ "Person 1: " ++ show person1
  putStrLn $ "Person 2: " ++ show person2

输出

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
Person 1: Person {name = "Alice", age = 25}
Person 2: Person {name = "Alice clone", age = 25}

示例 4

在此示例中,我们使用记录语法定义了 Person 数据类型和一个函数 clonePerson,该函数接受一个 Person 并返回一个具有相同属性但名称后缀为 " clone" 的新 Person。

data Person = Person { name :: String, age :: Int } deriving (Show)

clonePerson :: Person -> Person
clonePerson p = p { name = name p ++ " clone" }

main :: IO ()
main = do
  let person1 = Person { name = "Alice", age = 25 }
      person2 = clonePerson person1
  putStrLn $ "Person 1: " ++ show person1
  putStrLn $ "Person 2: " ++ show person2

输出

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
Person 1: Person {name = "Alice", age = 25}
Person 2: Person {name = "Alice clone", age = 25}

结论

在 Haskell 中,数据类型可以有多个构造函数。一个构造函数可以通过使用与数据类型相同的名称和模式匹配来调用另一个构造函数。这称为记录语法,其中构造函数可以具有与数据类型属性相对应的命名字段。

更新于: 2023-03-28

176 次浏览

开启您的 职业生涯

通过完成课程获得认证

开始学习
广告