在Haskell记录初始化中强制关键字参数

k97glaaz  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(136)

在Haskell中初始化一个记录时,我可以 * 强制只使用关键字 * 吗?

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

main = putStrLn $ show $ Person "oren" "9200"

-- I want to only allow such initializations:
-- main = putStrLn $ show $ Person { name = "moish", idnum = "7400" }

(This在两个字段具有相同类型时特别有用)

unhi4e5o

unhi4e5o1#

据我所知,没有。
也许可以考虑以下解决方案?

newtype Name = Name String
newtype Idnum = Idnum String

data Person = Person { name :: Name, idnum :: Idnum }

另一种可能性,在我看来更糟的是:

module A (Person, name, idnum) where

data Person = Person
  { _name :: String
  , _idnum :: String
  }

name :: String -> (Person -> Person)
name n p = p { _name = n }

idnum :: String -> (Person -> Person)
idnum n p = p { _idnum = n }

emptyPerson :: Person
emptyPerson = Person "" ""

# in another module

module B

import A (Person, name, idnum)

myPerson = name "myname" . idnum "myidnum" $ emptyPerson

在这种情况下,不能保证nameidnum都得到一个值。
Person总是可以作为一个“普通函数”使用,这一点可能会非常有用。例如,如果你有getName :: IO StringgetIdnum :: IO String,那么把它们组合起来形成一个getPerson :: IO Person是简洁的:getPerson = Person <$> getName <*> getIdnum。这是唯一可能的,因为我们 * 不 * 使用记录语法在这里!

相关问题