从 GHCi 使用 RecordWildCards 扩展时出错

Error when using RecordWildCards extension from GHCi

我创建了一个函数,它使用 RecordWildCards 语法在 Haskell 记录类型上进行模式匹配:

编译指示

我已将编译指示放在文件的顶部。我也尝试用 :set -XRecordWildCards.

添加它
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}

类型定义

data ClientR = GovOrgR { clientRName :: String }
                | CompanyR { clientRName :: String,
                            companyId   :: Integer,
                            person      :: PersonR,
                            duty        :: String
                          }
                | IndividualR { person :: PersonR }
                deriving Show

data PersonR = PersonR {
                          firstName :: String,
                          lastName  :: String
                       } deriving Show

函数

greet2 :: ClientR -> String
greet2 IndividualR { person = PersonR { .. } } = "hi" ++ firstName ++ " " ++ lastName + " "
greet2 CompanyR { .. } = "hello " ++ firstName ++ " " ++ lastName ++ "who works as a " ++ duty ++ " " ++ clientRName + " "
greet2 GovOrgR {} = "Welcome"

错误

    • Couldn't match expected type ‘[Char]’
                  with actual type ‘PersonR -> String’
    • Probable cause: ‘lastName’ is applied to too few arguments
      In the first argument of ‘(++)’, namely ‘lastName’
      In the second argument of ‘(++)’, namely
        ‘lastName ++ "who works as a " ++ duty ++ " " ++ clientRName + " "’
      In the second argument of ‘(++)’, namely
        ‘" "
         ++
           lastName ++ "who works as a " ++ duty ++ " " ++ clientRName + " "’
Failed, modules loaded: none.

当我在 CompanyR 上使用此函数以使用 as pattern 匹配 PersonR 时,我得到:

函数

greet2 c@(CompanyR { .. }) = "hello " ++ (firstName $ person c) ++ " " ++ (lastName $ person c) 

错误

Couldn't match expected type ‘ClientR -> PersonR’
                  with actual type ‘PersonR’
    • The function ‘person’ is applied to one argument,
      but its type ‘PersonR’ has none
      In the second argument of ‘($)’, namely ‘person c’
      In the first argument of ‘(++)’, namely ‘(firstName $ person c)’

    • Couldn't match expected type ‘ClientR -> PersonR’
                  with actual type ‘PersonR’
    • The function ‘person’ is applied to one argument,
      but its type ‘PersonR’ has none
      In the second argument of ‘($)’, namely ‘person c’
      In the second argument of ‘(++)’, namely ‘(lastName $ person c)’

你在这里的第一个案例中做对了(尽管我在你有 + 的地方修复了 ++):

greet2 :: ClientR -> String
greet2 IndividualR { person = PersonR { .. } } = "hi" ++ firstName ++ " " ++ lastName ++ " "

但此处 firstName 等不是 CompanyR 中的记录,因此 CompanyR { .. } 不会将它们纳入范围:

greet2 CompanyR { .. } = "hello " ++ firstName ++ " " ++ lastName ++ "who works as a " ++ duty ++ " " ++ clientRName + " "

您必须像在 greet2 的第一个案例中那样做一些事情,就在上面:

greet2 CompanyR {person = PersonR { .. }, .. } = "hello " ++ firstName ++ " " ++ lastName ++ "who works as a " ++ duty ++ " " ++ clientRName ++ " "